0

I want to make script to search one file in more than one directory, for example I have structure of dir's:

 -images
   --2014
   --2015
   --2016

Now my PHP script should search FILE.jpg in one of 2014/2015/2016 (folders will be create dynamically, so I can't put list of folders in script (just folder 'images' will be always).

Best regards!

Mateusz Ji
  • 59
  • 2
  • 8

2 Answers2

0

You can merely use glob().
In the precise case you describe it should look like this:

$files = glob('path_to_images/*/FILE.jpg');

More generally, put as many /* as needed between the known folder path and the searched file name to explore a given depth level.


Edit, extending the solution according to the OP's comment

If you don't know anything about the tree structure, you can do a deep multi-level search, like this:

function doGlob($target, $context) {
  if ($dirs = glob($context . '/*', GLOB_ONLYDIR)) {
    foreach ($dirs as $dir) {
      $result = array_merge($result, doGlob($target, $dir));
    }
  }
  return $result;
}
$files = doGlob('FILE.jpg', 'path_to_images');

It'll return all occurrences of $target file anywhere in the given $context.

Caution: it may be much time consuming if context is a big structure!

So you might limit the search depth, like this:

function doGlob($target, $context, $max_depth = -1, $depth = 0) {
  $result = glob($context . '/' . $target);
  if ($depth > $max_depth) {
    return $result;
  }
  if ($dirs = glob($context . '/*', GLOB_ONLYDIR)) {
    foreach ($dirs as $dir) {
      $result = array_merge($result, doGlob($target, $dir, $max_depth, $depth + 1));
    }
  }
  return $result;
}
$files = doGlob('FILE.jpg', 'path_to_images', <max-depth>);

In the other hand, if you plan to retrieve only a unique file, you might more simply stop as soon as it's found:

function doGlob($target, $context) {
  if ($result) {
    return $result;
  }
  if ($dirs = glob($context . '/*', GLOB_ONLYDIR)) {
    foreach ($dirs as $dir) {
      $result = array_merge($result, doGlob($target, $dir));
    }
  }
  return $result;
}
$files = doGlob('FILE.jpg', 'path_to_images');
cFreed
  • 4,404
  • 1
  • 23
  • 33
  • it's propably the best idea but if I don't know how many sub-folder it will have? It can be images/2014 or images/2014/02 or images/2014/02/02, etc. – Mateusz Ji Feb 26 '16 at 17:01
0

You can use scandir too:

function search($d)
{
    $dir=scandir($d);
    echo '<ul>';
    foreach ($dir as $key => $value) 
    {
        if($value!='.' && $value!='..')
        {
            if(is_dir($d.'/'.$value))
            {
                echo "<li>".$value."</li>";
                search($d.'/'.$value);
            }

            else
                echo "<li>".$value."</li>";

        }
    }

    echo '</ul>';
}

search('images');

In this example, I display all files but you can add a condition:

function search($d, $search)
{
    $dir=scandir($d);
    echo '<ul>';
    foreach ($dir as $key => $value) 
    {
        if($value!='.' && $value!='..')
        {
            if(is_dir($d.'/'.$value))
            {
                echo "<li>".$value."</li>";
                search($d.'/'.$value, $search);
            }

            else
            {
                echo "<li>".$value."</li>";
                if($value==$search)
                    echo "found";

            }

        }
    }

    echo '</ul>';
}

search('images', 'your_file');
MisterDebug
  • 915
  • 9
  • 15