Recursive PHP Function.. Works but doesnt?

WalkedAirplane

Limp Gawd
Joined
Apr 19, 2005
Messages
378
Can anyone help me out with why the below isnt working? It returns the value I want, but when placed inbetween two strings to actually display the image, it ignores the variable totally.

Code:
            function getMostRecent($id){
                if(file_exists("./images/000".$id.".jpg")){
                    $id++;
                    getMostRecent($id);
                }
                else{ 
                    $id--;
                    echo $id;
                    return $id;
                }
            }

The echo $id; line works fine - the number shows up.

if I run
echo getMostRecent(1) I get the correct value printed on screen.

However, if I us it here:
Code:
             displayImg(getMostRecent(1));

             function displayImg($picID){
                echo "<img src=\"./images/000".$picID.".jpg\">";
                
            }

I just get <img src=./images/000.jpg> even though $picID should be 2.

Any ideas?
 
First off, I'd clean up your quote marks and use ticks within double quotes; Also be careful of escaping. Have you tried chunking it? I like to make variables where possible so theres less garble in areas that are hard to read. Something like so:
Code:
$img = "images/000" . $picID . "\.jpg";
echo "<img src=$img>";

It looks like your period may be unescaped in your current code ... but it seems to be showing up ... when you get 000.jpg. Maybe it's doing that as a precaution thought and not bc the code is putting it there. I usually can get away with periods inside of quotes, but sometimes they can be tricky; Especially with concatenation.

Dunno if this helps/works at all without all the code but its worth a shot. I've ran into a lot of similar problems when making image loaders when reading directories. The hints above resolved MOST of my issues.
 
you are passing your argument by value, not by reference, a copy of $id is pushed onto the stack, not the real thing. So the original $id won't get changed.
You need to either pass by reference (not sure if PHP supports this), or return the value.
 
How would I return the value instead of a copy of $id then? I think I follow, but I may not be getting it either :confused: (just started toying with PHP today)
 
Code:
function getMostRecent($id)
{
    if (file_exists("./images/000".$id.".jpg"))
        return getMostRecent($id++);
    else 
        return $id--;        
}
 
yeah, you forgot to return the recursive call. just add a return in front of your recursive function's recursive call. i dont know if fryguy's solution works because the increment occurs after the instruction is executed.
 
yah after I hit send I realized I needed to pre-increment, but yah, you got the idea and figured it out :(
 
It looks like you're trying to print a link to the most recent file in a directory. Recursion is overkill for this task, even if you want to do it with a thousand stat() calls. Write a for loop instead, or figure out something smarter. You're not maintaining any state about that file, so there's no need to create the stack recursion implies.
 
Now to it with a recursive binary search... for performance!!
 
or maybe just get a list of the directory contents and pull the latest file from there.
 
or maybe just get a list of the directory contents and pull the latest file from there.

Which bring up a good point to avoid stat'ing everything ..... if you give apache the directory URL with parameters it will sort by date (as well as other things) in either order. Too bad you cant read from something like http://mysite.com/myfolder/?C=M;O=D which orders by newest first. You could then just parse your results. It may throw your code for a loop with the parameters unless you can decode it first.
 
Which bring up a good point to avoid stat'ing everything ..... if you give apache the directory URL with parameters it will sort by date (as well as other things) in either order. Too bad you cant read from something like http://mysite.com/myfolder/?C=M;O=D which orders by newest first. You could then just parse your results. It may throw your code for a loop with the parameters unless you can decode it first.
'ls' knows how to sort files by time:
Code:
strace ls -t
execve("/bin/ls", ["ls", "-t"], [/* 35 vars */]) = 0
...
lstat64("apache_pb22.gif", {st_mode=S_IFREG|0644, st_size=2410, ...}) = 0
lstat64("index.html", {st_mode=S_IFREG|0644, st_size=44, ...}) = 0
lstat64("apache_pb22.png", {st_mode=S_IFREG|0644, st_size=1502, ...}) = 0
lstat64("apache_pb22_ani.gif", {st_mode=S_IFREG|0644, st_size=2205, ...}) = 0
lstat64("apache_pb.gif", {st_mode=S_IFREG|0644, st_size=2326, ...}) = 0
...
I imagine Apache does something similar to get its list of files in order by time.

My solution would be a bit different. Create a symlink to the most recent file, and just read that. Sure, there's a bit of overhead associated with reading a symlink, but it doesn't get more expensive to read that link as more files are placed in that directory. If you've got a process creating files, have it also update the symlink.

I'm kind of guessing that you're on a Unix-like platform; if not, try creating a file with the name of the current jpeg file in it. Open it, read it, then process that file.
 
What happens if a file is deleted somewhere? Your solution will break. Generally speaking, it is a good idea to have meta data associated with images. The most popular and easy method would be a database table for images. This way it's as easy as querying the database. Just a thought.
 
Back
Top