在PHP中递归收集图像文件路径

在PHP中递归收集图像文件路径,php,iteration,Php,Iteration,我正在处理一个相当大的PHP类,它从命令行执行大量图像优化工作,您基本上会向程序传递一个图像路径或一个文件夹路径,其中包含多个图像。然后,它通过多达5个其他命令行程序运行这些文件,以优化图像 下面是收集图像路径的循环的一部分,如果路径是文件夹而不是图像路径,它将迭代文件夹中的所有图像,并将它们添加到图像数组中 到目前为止,我的一切工作为单一的图像和图像在1个文件夹。我想修改下面的这一部分,这样它就可以递归地深入1个文件夹来获取图像路径 有没有人能告诉我如何修改下面的内容来实现这一点 // Get

我正在处理一个相当大的PHP类,它从命令行执行大量图像优化工作,您基本上会向程序传递一个
图像路径
或一个
文件夹路径
,其中包含多个图像。然后,它通过多达5个其他命令行程序运行这些文件,以优化图像

下面是收集图像路径的循环的一部分,如果路径是文件夹而不是图像路径,它将迭代文件夹中的所有图像,并将它们添加到图像数组中

到目前为止,我的一切工作为单一的图像和图像在1个文件夹。我想修改下面的这一部分,这样它就可以递归地深入1个文件夹来获取图像路径

有没有人能告诉我如何修改下面的内容来实现这一点

// Get files 
if (is_dir($path))
{
    echo 'the path is a directory, grab images in this directory';
    $handle = opendir($path);
    // FIXME : need to run recursively
    while(FALSE !== ($file = readdir($handle))) 
    {
        if(is_dir($path.self::DS.$file))
        {
            continue;
        }
        if( ! self::is_image($path.self::DS.$file))
        {
            continue;
        }
        $files[] = $path.self::DS.$file;
    }
    closedir($handle);



}else{
    echo 'the path is an Image and NOT a directory';
    if(self::is_image($path))
    {   
        echo 'assign image Paths to our image array to process = '. $path. '<br><br>';
        $files[] = $path;
    }
}

if (!count($files))
{
    throw new NoImageFoundException("Image not found : $path");
}


创建一个递归函数来读取目录,如果在循环过程中找到目录,则进一步读取

大致如下:

$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));

while ($it->valid())
{
  if ($it->isDot())
    continue;

  $file = $it->current();
  if (self::is_image($file->pathName))
  {
    $files[] = $file->pathName;
  }

  $it->next();
}
函数r\u readdir($path){
静态$files=array();
如果(!is_dir($path)){
echo“路径是图像而不是目录”;
if(self::is_image($path))
{   
echo“将图像路径分配给要处理的图像数组=”。$path。“

”; $files[]=$path; } }否则{ while(FALSE!=($file=readdir($handle))) { if(is_dir($path.self::DS.$file)) { r_readdir($path.self::DS.$file); } 如果(!self::is_image($path.self::DS.$file)) { 继续; } } closedir($handle); } 返回$files; }
虽然andreas的答案可能有效,但您也可以让PHP5为您做这件事,并使用更面向对象的方法

下面是一个简单的例子:

$it = new RecursiveIteratorIterator(
                new RecursiveRegexIterator(
                    new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::KEY_AS_PATHNAME),
                    '/^(?!.*(\.svn|\.cvs)).*$/', RecursiveRegexIterator::MATCH
                ),
                RecursiveIteratorIterator::SELF_FIRST
            );

foreach ($it as $dir => $info)
{
  var_dump($dir); 
}
编辑:

或者,您可以尝试以下方法(从Zend_Translate_适配器复制):

干杯


Chris

例如,谢谢你,事实上,我不得不在andreas代码中添加很多他遗漏的东西,比如路径没有分配给数组或其他任何东西,它没有正确迭代。我知道他有正确的想法。你的路线是我想走的路,但我仍然有一些问题,就在
if($it->isDot()){
下面,我添加了一条回音消息以查看发生了什么,下面是它检查图像的地方,然后我运行脚本,但它进入了一个无限循环,显示我为
if($it->isDot()设置的消息){
…继续下一条消息…我正在测试的结构是一个包含4个图像的文件夹和一个包含另外4个图像的文件夹。因此,我运行它的文件夹有4个图像和1个子文件夹,该子文件夹也有4个图像。还有其他提示,请感谢帮助。这很奇怪,你在其中有符号链接吗?这是svn还是git项目?当您转储
$it->current()
时会发生什么?您看到了发生了什么吗?我添加了另一种方式(Zend的方式)这将应用RegexIterator来排除某些目录,您可能想尝试一下。当您发布此内容时,我正在处理我在文档中找到的某个内容,它似乎工作得很好,如果您想查看,我会将其添加到上面问题的底部。好的,很高兴它对您有效。也许这是windows方面的事情,我测试了我的代码,它对您有效me.cheers您可以将
recursiveiterator
的(默认)
LEAVES\u ONLY
模式与
recursivedirectoryterator
SKIP\u DOTS
选项结合使用。这将允许您跳过循环内部的
isDir()
检查。我还建议使用
getPathname()
取代了
\uuu-toString()
(更具描述性)。非常适合
getPathname()
我想找一个更好的,但是我试过的其他文件只显示了文件名,所以这很好。我得看看你提到的其他东西,thanks@salethe我找不到太多关于递归迭代器与跳过点的“只剩下叶子”模式的信息,你能告诉我如何实现它吗?将这些类常量放置在递归迭代器(
$mode
)和递归DirectoryIterator(
$flags
)的构造函数中分别。@salethe谢谢!我在过去的一个小时里一直在玩测试,从目前为止我所知道的…将
recursiveiterator::CHILD_FIRST
更改为
recursiveiterator::LEAVES_ONLY
阻止任何目录显示,即使没有使用
recursivedirectoryinterator::SKIP_DOTS
I am你知道这件事吗?我不确定什么是
只剩下
孩子
在做什么
(
    [0] => E:\Server\_ImageOptimize\img\testfiles\css3-generator.png
    [1] => E:\Server\_ImageOptimize\img\testfiles\css3-please.png
    [2] => E:\Server\_ImageOptimize\img\testfiles\css3-tools-10.png
    [3] => E:\Server\_ImageOptimize\img\testfiles\fb.jpg
    [4] => E:\Server\_ImageOptimize\img\testfiles\mysql.gif
    [5] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\css3-generator.png
    [6] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\css3-please.png
    [7] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\css3-tools-10.png
    [8] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\fb.jpg
    [9] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\mysql.gif
    [10] => E:\Server\_ImageOptimize\img\testfiles\OriginalImages\support-browsers.png
    [11] => E:\Server\_ImageOptimize\img\testfiles\support-browsers.png
)
function r_readdir($path) {
   static $files = array();
   if(!is_dir($path)) {
      echo 'the path is an Image and NOT a directory';
      if(self::is_image($path))
      {   
         echo 'assign image Paths to our image array to process = '. $path. '<br><br>';
         $files[] = $path;
      }
   } else {
      while(FALSE !== ($file = readdir($handle))) 
      {
         if(is_dir($path.self::DS.$file))
         {
            r_readdir($path.self::DS.$file);
         }
         if( ! self::is_image($path.self::DS.$file))
         {
            continue;
         }
      }
      closedir($handle);
   }
   return $files;
}
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));

while ($it->valid())
{
  if ($it->isDot())
    continue;

  $file = $it->current();
  if (self::is_image($file->pathName))
  {
    $files[] = $file->pathName;
  }

  $it->next();
}
$it = new RecursiveIteratorIterator(
                new RecursiveRegexIterator(
                    new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::KEY_AS_PATHNAME),
                    '/^(?!.*(\.svn|\.cvs)).*$/', RecursiveRegexIterator::MATCH
                ),
                RecursiveIteratorIterator::SELF_FIRST
            );

foreach ($it as $dir => $info)
{
  var_dump($dir); 
}