I took this from a different thread, but here it is, then my question...

<?php

function preg_ls ($path=".", $rec=false, $pat="/.*/") {
    // it's going to be used repeatedly, ensure we compile it for speed.
    $pat=preg_replace("|(/.*/[^S]*)|s", "\\1S", $pat);
    //Remove trailing slashes from path
    while (substr($path,-1,1)=="/") $path=substr($path,0,-1);
    //also, make sure that $path is a directory and repair any screwups
    if (!is_dir($path)) $path=dirname($path);
    //assert either truth or falsehoold of $rec, allow no scalars to mean truth
    if ($rec!==true) $rec=false;
    //get a directory handle
    $d=dir($path);
    //initialise the output array
    $ret=Array();
    //loop, reading until there's no more to read
    while (false!==($e=$d->read())) {
        //Ignore parent- and self-links
        if (($e==".")||($e=="..")) continue;
        //If we're working recursively and it's a directory, grab and merge
        if ($rec && is_dir($path."/".$e)) {
            $ret=array_merge($ret,preg_ls($path."/".$e,$rec,$pat));
            continue;
        }
        //If it doesn't match, exclude it
        if (!preg_match($pat,$e)) continue;
        //In all other cases, add it to the output array
        $ret[]=$path."/".$e;
    }
    //finally, return the array
    return $ret;
}

foreach (preg_ls("/home/username/example.com/sites/default/files", true, "/.*\.jpg/i") as $file) echo $file;

?>

And it works, but the output is suppose to be
/home/username/example.com/sites/default/files/file1.jpg
/home/username/example.com/sites/default/files/file2.jpg
/home/username/example.com/sites/default/files/file3.jpg

But the output is returning...
/home/username/example.com/sites/default/files/
file1.jpg/home/username/example.com/sites/default/files/
file2.jpg/home/username/example.com/sites/default/files/
file3.jpg/home/username/example.com/sites/default/files/
file4.jpg/home/username/example.com/sites/default/files/
file5.jpg/home/username/example.com/sites/default/files/file6.jpg

Just like that... Why??? I'm so confused.

Comments

nevets’s picture

Looking at the behavior and not trying to understand every line I would try replacing

        $ret[]=$path."/".$e;

with

        $ret[]=$path."/". trim($e);
christopherareed’s picture

Testing that change now... ... ... *jeopardy music plays* ... ... ... Same result as above =( Thanks for the speedy response though! Any other ideas?

nevets’s picture

Ok, for grins this time change

        $ret[]=$path."/".$e;

to

        $ret[]='[[' . $path."/".$e . ']]';

This will let you see what the elements of $ret are (and not have me guessing).

christopherareed’s picture

Testing again! Also thanks again! *Refreshes output* Hmm, interesting... it came out as this...

[[/home/username/example.com/sites/default/files/file1.jpg]]
[[/home/username/example.com/sites/default/files/file2.jpg]]
[[/home/username/example.com/sites/default/files/file3.jpg]]
[[/home/username/example.com/sites/default/files/file4.jpg]]
[[/home/username/example.com/sites/default/files/file5.jpg]]
[[/home/username/example.com/sites/default/files/file6.jpg]]

So can you elaborate a little, for the less knowledgable like myself?

nevets’s picture

Ok, that's "interesting".

That tells us the $ret holds what you want, each string between '[[' and ']]' is one element of $ret. Whats odd is where the newlines come from (there should not be any). And dman's answer below is the simpler solution.

christopherareed’s picture

Yeah, that's what has been driving me nuts. It may be the simpler solution below, but I'm stubborn and little things like that bug me to no end. I'll definitely take a look at the file_scan_directory function in a minute. Do you want to help me pursue this anomaly or should I just concede and move on, hah.

nevets’s picture

While willing to help I am not sure what to suggest. echo does not output newlines (at least it should not) and your code as posted does not show it outputting any "\n", so your output should run together. Then adding '[[' and ']]' changes where the newlines show. It is like your posted code and the actual code have some small difference. And while willing to help, I will not return till later for the hour is late here and slumber calls. Personally I would pick the simpler solution (at least if I needed one now).

christopherareed’s picture

BTW, my goal is to count the # of files in a directory and list the contents if X criteria is met, then display the file path of each individual file. Since I didn't state that originally.

nevets’s picture

Try the above to see what you get.

Also a question are you using php 4 or php 5?

christopherareed’s picture

Hehe, we're replying at the same time, and it's php 5.2.6.

dman’s picture

Would file_scan_directory() be useful for you?
;-)

christopherareed’s picture

Well, thanks for that dman! I can't seem to get the syntax right though... Anyway you could give a simple example of it in use?

dman’s picture

The API has a useful reverse lookup. "9 functions call file_scan_directory()" which is a good place to start always.
The syntax requires a regexp (without the bounding stuff) so a normal filesystem * wildcard needs to be .* so as in image_get_available_toolkits()
$toolkits = file_scan_directory('includes', 'image\..*\.inc$');
will return a list of all "includes/image/*/*.inc" files. (dunno why it's formatted in two parts there - something about deeper recursion being allowed I think.)
or install_find_locales() uses
$locales = file_scan_directory('./profiles/'. $profilename .'/translations', '\.po$', array('.', '..', 'CVS'), 0, FALSE);
to find 'profiles/profilename/translations/*.po (non-recursive)

You will probably be OK with
file_scan_directory("/home/username/example.com/sites/default/files", ".*\.jpg");
Although as best practice goes, try
file_scan_directory( file_directory_path(), '.*\.jpg$');
(figure out case-insensitivity yourself - '.*\.[jJ][pP][gG]$' - I dunno)

christopherareed’s picture

Ah I still can't seem to get it to work properly... the file_scan_directory("/home/username/example.com/sites/default/files", ".*\.jpg"); just returns the word Array when displayed and nothing else, and I've tried everything else I can think of...

nevets’s picture

How about trying

<?php
$files =  file_scan_directory("/home/username/example.com/sites/default/files", ".*\.jpg");
foreach (  $files as $filename => $file ) {
   print "$filename:<pre>"  . print_r($file,  TRUE) . '</pre>';
}
?>
christopherareed’s picture

Testing that suggestion right now. Even something like this...


$directory = "../images/example/";
 
$images = glob("" . $directory . "*.jpg");
 
foreach($images as $image)
{
echo $image;
}

Returns with the same problem as above with the line breaks for no reason like we previously ran into... I'll write back once I test your new suggestion though.

dman’s picture

That is correct.
The return value form file_scan_directory is a list of arrays. Each array contains handy information about the file - not just the string filename. Yes. an array.
just run a print_r on the return value and you'll see everything.
You can also just use array_keys() to get just the filename.