在 PHP 中合并目录迭代器数组时出现问题


Issue merging DirectoryIterator arrays in PHP

我在尝试为我正在处理的项目将几个数组合并在一起时遇到问题。我越来越接近预期的结果,我已经搜索了这个网站,但找不到可行的解决方案。

我怀疑这很重要,但这个项目正在 IIS 上进行测试,但最终结果必须在 IIS 和 Apache 上工作。

所以在这里...我需要按字母顺序合并和排序四个目录。

$dir1 = "D:''dir1";
$dir2 = "D:''dir2";
$dir3 = "D:''dir3";
$dir4 = "D:''dir4";
$dirA = array($dir1,$dir2,$dir3,$dir4);

如果我执行以下操作,我将"接近"我需要的结果:

try
{
  $object = new ArrayIterator($dirA);
  foreach($object as $key=>$value)
  {
    foreach(new DirectoryIterator($value) as $item)
    {
      if(!$item->isDot())
      {
        echo $item->getFilename() .' ';
        if(file_exists($value.''''.$item.''folder.jpg'))
        {
          echo 'Y<br />';
        } else {
          echo 'X<br />';
        }
      }
    }
  }
}
catch(Exception $e)
{
  echo $e->getMessage();
}

并最终得到每个目录中的文件夹列表(按字母顺序),但它们不会合并,而是仍然按$item->key()对它们进行分组(我想这就是我实际尝试合并的内容?我尝试了许多使用array_merge的方法,但没有成功)

我尝试使用 sortksort 等,但要么它们不起作用,要么在我echo列表之前我无法弄清楚它的正确位置。

我的最终目标是将整个事情echo到一个表中,我在其中使用多个file_exists来检查每个文件夹中"应该"可用的特定文件......例如,每个都应该在其根目录中有一个"文件夹.jpg",所以我希望它显示以下内容:

Folder Name            folder.jpg      (other files to be verify)
Directory1                 Y            Y   Y   Y   Y   Y
Directory2                 Y            Y   X   Y   Y   Y
Directory3                 X            X   Y   X   X   X
Directory4                 Y            Y   Y   Y   Y   Y

--
希望以上内容不会令人困惑并提供足够的信息,我要感谢任何能够提供帮助的人,并邀请任何愿意帮助该项目的人与我联系(我显然会在相应的领域归功于这个人)。

再次感谢。

--
编辑:试图澄清一点。

最后,该项目会将某些变量写入"设置.ini并读取这些变量(我有该部分工作正常,所以我现在完全忽略它并将所有内容本地写入单个文件中)。

就我而言,我在不同的驱动器上有 4 个文件夹,每个文件夹都有 15 到 130 个子目录(所有唯一名称)。因此,缩写列表类似于:

T:'New Set'
     A'
     D'
     G'
D:'Old Set'
     B'
     F'
  etc.
---------
$dir1 = 'T:/New Set';
$dir2 = 'D:/Old Set';
$dir3 = 'D:/Overage';
$dir4 = 'G:/Unsorted';
$dirA = array($dir1,$dir2,$dir3,$dir4);

使用我最初在上面发布的代码会给我如下所示的代码(而不是按字母顺序排列)

A  // from $dir1
D  // from $dir1
G  // from $dir1
B  // from $dir2
F  // from $dir2
etc.

使用DaveRandom发布的代码,它显示了以下内容:

Array ( [T:'New Set] => Array ( [folder.jpg] => 1 [cover.jpg] => [poster.jpg] => ) [D:'Old Set] => Array ( [folder.jpg] => 1 [cover.jpg] => [poster.jpg] => ) [D:'Overage] => Array ( [folder.jpg] => 1 [cover.jpg] => [poster.jpg] => ) [G:'Unsorted] => Array ( [folder.jpg] => 1 [cover.jpg] => [poster.jpg] => ) )
Folder Name folder.jpg  cover.jpg   poster.jpg
T:'New Set  Y   X   X
D:'Old Set  Y   X   X
D:'Overage  Y   X   X
G:'Unsorted Y   X   X

我想现在,我唯一的问题是仅对子目录进行排序,因为我能够验证文件并以其他方式执行表。所以为了清楚起见,我希望目录数组不要像上面那样显示,而是像下面这样显示:

A  // from $dir1
B  // from $dir2
D  // from $dir1
F  // from $dir2
G  // from $dir1
etc.

我对你的问题有点困惑,但我认为对于你要做的事情,你最好在 2D 数组中构建一个类似表格的数据结构,然后你可以迭代它以显示为表格。您可以一次性完成所有操作,但它将使您的代码更具可读性/可维护性,以分离数据采集和显示生成逻辑。

我还认为您在自己的脑海中用目录迭代器大大复杂化了这个问题。您真正要做的(基于您的示例输出)是检查目录列表顶层是否存在某些文件 - 在这种情况下,您需要做的就是迭代目录列表,然后迭代您正在寻找的文件列表。

我在这里也真的看不到 ArrayObject/ArrayIterator 中的意义,因为您没有修改正在使用的数组。您可以只循环数组本身。

这样:

已编辑以反映评论。您在这里需要的排序魔法来自array_multisort()

// Don't forget to escape ' backslashes!
// Also, / works on Windows too...
$dirA = array(
  "D:''dir1",
  "D:''dir2",
  "D:''dir3",
  "D:''dir4"
);
// The list of files you are checking for
$files = array(
  'folder.jpg',
  'cover.jpg',
  'poster.jpg'
);
// The "columns" we want to sort by (highest priority first)
// This is equivalent to SQL: ORDER BY name ASC, path ASC
$sortCols = array(
  'name' => SORT_ASC,
  'path' => SORT_ASC
);
// This will be our results "table"
$results = array();
// This will hold the sort column items
$sortInfo = array();
foreach ($sortCols as $colName => $flags) {
  $sortInfo[$colName] = array();
}
// Loop parent directories
foreach ($dirA as $dir) {
  // Make a DirectoryIterator and loop it
  foreach (new DirectoryIterator($dir) as $child) {
    // Skip files and parent dir
    if (!$child->isDir() || $child->isDot()) {
      continue;
    }
    // Temp array to hold data about this sub-dir
    $result = array();
    $result['path'] = $child->getPathname();
    $result['name'] = basename($result['path']);
    // Now check for the existence of files in the file list
    // You might want to use is_file() instead of file_exists() since
    // it is possible for there to be a directory named 'folder.jpg'
    foreach ($files as $file) {
      $result[$file] = file_exists($result['path'].''''.$file);
    }
    // Create a "row" for this sub-directory
    $results[] = $result;
    // Create sort data for this directory
    foreach ($sortCols as $colName => $flags) {
      $sortInfo[$colName][] = $result[$colName];
    }
  } // foreach DirectoryIterator
} // foreach $dirA
// Now we have an array of "rows" corresponding to each sub-directory
// we can do some sorting magic with it.
// First we prepare the data to pass to array_multisort() as an array
// of arguments, which we can use with call_user_func_array(). This
// approach allows a dynamic number of sort columns.
$sortData = array();
foreach ($sortCols as $colName => $flags) {
  $sortData[] = $sortInfo[$colName];
  $sortData[] = $flags;
}
$sortData[] = &$results; // Last arg is passed by reference!
// Now we call it
call_user_func_array('array_multisort', $sortData);

// Now we output a table
echo "<table>'n";
// Header row
echo "<tr><th>Folder Name</th><th>Full Path</th>";
foreach ($files as $file) {
  echo "<th>$file</th>";
}
echo "</tr>'n";
// Data rows
foreach ($results as $row) {
  echo "<tr><td>{$row['name']}</td><td>{$row['path']}</td>";
  foreach ($files as $file) {
    echo $row[$file] ? "<td>Y</td>" : "<td>X</td>";
  }
  echo "</tr>'n";
}
echo "</table>";