2

I have a script that scans a folder and put in an array the file names it contains. Then I shuffle the array and display the file names.

Like this:

$count=0;
$ar=array();
$i=1;
$g=scandir('./images/');

foreach($g as $x)
{
    if(is_dir($x))$ar[$x]=scandir($x);
    else 
    { 
        $count++;
        $ar[]=$x;   
    }
}
shuffle($ar);

while($i <= $count)
{
    echo $ar[$i-1];
    $i++;
}
?>

It works well but for some reason I get something like this:

  • fff.jpg
  • ccc.jpg
  • Array
  • nnn.jpg
  • ttt.jpg
  • sss.jpg
  • bbb.jpg
  • Array
  • eee.jpg

Of course, the order changes when I refresh the page because of the shuffle I did but among 200 filenames I always get these 2 "Array" somewhere in the list.

What could it be?

Thank you

Baylock
  • 1,246
  • 4
  • 25
  • 49
  • 2
    [glob()](http://php.net/manual/en/function.glob.php) is much more fun –  May 13 '15 at 23:44
  • @Dagon *blob blob* I think that would be fish :) Do you mean glob ? – Rizier123 May 13 '15 at 23:47
  • I'll look for glob, thank you. In the meantime, I would like to know what is going wrong with the script as it is (the first one). Here in my example, I just "echo" the filenames to make it simple but I need more than that. So I need to store the names in an array for a later use. I believe that, glob or not, I will end up with the exact same issue. – Baylock May 13 '15 at 23:49
  • if you need to recursively search thru the directories, you can use SPL libraries for that also http://stackoverflow.com/questions/20045622/php-recursivedirectoryiterator – Kevin May 13 '15 at 23:57
  • There's nothing recursive. There is only one folder and no subfolders. If you remove the "is_dir" part, the result would be just the same: "Array" is still displayed. I'm not asking for a workaround here, I would only like to know why the "Array" keep appearing in the list with this very script. It's more about understanding the problem than solving it (both would be nice). Thank you. – Baylock May 14 '15 at 00:07
  • 1
    @Baylock does `./images/` only contain images, or does it contain subfolders as well? do you need to look into its subfolders too for images? – Kevin May 14 '15 at 00:09
  • No, only pictures in it and no subfolders at all (double checked). – Baylock May 14 '15 at 00:10
  • If I remove the "is_dir" condition, it works. I just don't understand why it gets in the way as there are no subfolders anyway. It's beyond me. It reacts as if there were subfolders. – Baylock May 14 '15 at 00:17

1 Answers1

4

Just to explain the part wherein it gives you the Array.

First off, scandir returns the following:

Returns an array of files and directories from the directory.

From that return values, it returned this (this is an example, for reference):

Array
(
    [0] => . // current directory
    [1] => .. // parent directory
    [2] => imgo.jpg
    [3] => logo.png
    [4] => picture1.png
    [5] => picture2.png
    [6] => picture3.png
    [7] => picture4.png
)

Those dots right there are actually folders. Right now in your code logic, when it hits/iterate this spot:

if(is_dir($x))$ar[$x]=scandir($x); // if its a directory
// invoke another set of scandir into this directory, then append it into the array

Thats why your resultant array has mixed strings, and that another extra/unneeded scandir array return values from ..

A dirty quick fix could be used in order to avoid those. Just skip the dots:

foreach($g as $x)
{
    // skip the dots
    if(in_array($x, array('..', '.'))) continue;
    if(is_dir($x))$ar[$x]=scandir($x);
    else
    {
        $count++;
        $ar[]=$x;
    }
}

Another alternative is to use DirectoryIterator:

$path = './images/';
$files = new DirectoryIterator($path);
$ar = array();
foreach($files as $file) {
    if(!$file->isDot()) {
        // if its not a directory
        $ar[] = $file->getFilename();
    }
}

echo '<pre>', print_r($ar, 1);
Funk Forty Niner
  • 74,450
  • 15
  • 68
  • 141
Kevin
  • 41,694
  • 12
  • 53
  • 70
  • Thank you very much. That's it. The other contributors are probably right with their suggestions but I needed to know what happened here and your answer makes total sens. – Baylock May 14 '15 at 00:24
  • @Baylock sure glad this shed some light – Kevin May 14 '15 at 00:25
  • @Ghost: Correct me if I'm wrong; The only disadvantage to using these methods would be if you wanted to include directories that might be in the path. – l'L'l May 14 '15 at 00:55
  • @l'L'l are you referring to the extra example i added on `DirectoryIterator`, what do you mean _that might be path_? another extra folder, if the intent is to get those folder included? (not traverse into it), a minor tweak could be used, instead of `->isDir()` the OP can use `->isDot()` instead. actually i don't understand why the OP wants to have another `scandir` inside that level if he doesn't want to make a recursive search – Kevin May 14 '15 at 01:00
  • @Ghost: I'm not sure about the OPs use of the other `scandir` either. If the `->isDot` was used instead though would it not hide hidden files (eg. `.htaccess` )? I found that if I only wanted to hide the upper level directories but show everything else (files (hidden files included), and directories) glob seemed to be the most flexible method. I'm not trying to nitpick at your solution, so don't please don't take my comment as negative criticism - it's more to answer my own curiosity. – l'L'l May 14 '15 at 01:17
  • 1
    @l'L'l yes of course `glob` would be cool and flexible since it'll support even with wildcards and other stuff, sure no harm done. – Kevin May 14 '15 at 01:21
  • 2
    @Ghost: [Here's what I was thinking](http://ideone.com/p2vkkM) - feel free to add it to your answer if you think it's helpful, cheers :) – l'L'l May 14 '15 at 01:33
  • Gawd, I love a well-explained answer ;-) As we say in Italian: *Bravo* (well done). – Funk Forty Niner May 14 '15 at 01:35
  • @Fred-ii- yeah i felt i needed to step in and just explain what was happening, the OP hasn't got an actual explanation, but yeah as suggested by others, `glob` is cool like the alternative done by I'L'l – Kevin May 14 '15 at 01:43
  • 1
    Don't kid yourself; give yourself more credit. I thought you gave them a rather good explanation ;-) – Funk Forty Niner May 14 '15 at 01:45