2

我有一个数组中包含的数据,就像这样,

$file['info']['files'] = array(
    [0] => array(
         'length' => (int),
         'path' => array (
              [0] => 'file.txt',
         ),
    ),
    [1] => array(
         'length' => (int),
         'path' => array (
              [0] => 'directory one',
              [1] => 'file2.txt',
         ),
    ),
    [2] => array(
         'length' => (int),
         'path' => array (
              [0] => 'directory one',
              [1] => 'directory two',
              [2] => 'file3.txt',
         ),
    ),
);

$file['info']['files']数组可以包含任意数量的元素。每个数组中path包含的$file['info']['files']数组是我遇到问题的地方。

它包含有关文件结构的信息。如果仅存在 1 个元素,则它是一个文件。如果存在多个元素,则从顶部开始的每个元素都是下一个元素的父文件夹,最后一个元素是最后一个文件夹中的文件。以上面的示例为例,文件结构为

FILE file1.txt
FOLDER directory one
     FILE file2.txt
     FOLDER directory two
          FILE {file3.txt}

我想将这些数据提取到我自己的数组结构中,如下所示,

 $sortedFiles = array(
     'file1.txt' => (int),
     'directory one' => array(
         'file2.txt' => (int),
         'directory two' => array(
              'file3.txt' => (int),
         ),
     ),
 );

到目前为止我有这个代码,

foreach($file['info']['files'] as $file) {
    // LENGTH AND PATH ARE SET
    if(isset($file['length'], $file['path'])) {
        // GET COUNT OF FILE PATH ARRAY
        $count = count($file['path']);
        // SINGLE FILE
        if($count == 1) {
            $sortedFiles[$file['path'][0]] = $file['length'];
        // FILES IN DIRECTORY
        } else {
            // BUILD ARRAY STRUCTURE FOR DIRECTORIES
        }
    }
}

在将目录添加到数组时我遇到了麻烦。我可以手动完成,每次检查目录的数组是否存在,如果不创建它,如果它确实存在,则添加到它。我用下面的代码尝试了这个,但它只深入一个目录(代码在上面所说// BUILD ARRAY STRUCTURE的地方)。

// FOLDER NOT SET
if(!isset($files[$file['path'][0]])) {
    $sortedFiles[$file['path'][0]] = array($file['path'][1] => $file['length'],);
// FOLDER SET
} else {
    $sortedFiles[$file['path'][0]][$file['path'][1]] = $file['length'];
}

如何为每个存在的目录动态创建数组并添加所需的信息,同时记住目录结构可以是任意数量的级别?

感谢您花时间阅读我相当长的问题,我感谢任何人给我的任何帮助。

4

4 回答 4

3

您将需要递归调用您的函数,如下例所示:

function get_contents_dir( $dir )
{
    $names = array();

    if ( is_dir($dir) && is_readable($dir) )
    {
            foreach ( scandir($dir) as $file )
            {
                    if ( is_dir($dir."/".$file) && is_readable($dir."/".$file) )
                    {
                            $names[] = get_contents_dir($dir."/".$file);
                    }

                    if ( is_file($dir."/".$file) && is_readable($dir."/".$file) )
                    {
                            $names[] = $dir."/".$file;
                    }
            }
    }

    return $names;
}

该函数首先打开设置$dir的文件夹并扫描文件列表,将找到的每个文件添加到数组中,扫描文件夹后,return作为函数的返回值。

scandir()结果的条目(文件夹中的文件和文件夹列表)实际上是一个文件夹时,就会出现扭曲。如果发生这种情况,函数会从其内部递归调用(参见$names[] = get_contents_dir($dir."/".$file);从函数内部调用函数的行),并且子文件夹也将被索引。冲洗并重复,直到所有子文件夹都被索引。

如果您调用该函数并让它执行,将返回一个数组。数组的每个键都是一个条目。如果是文件,则链接到键的值是文件名,如果是文件夹,则值将是嵌套在前一个数组中的另一个数组。

以下是返回数组的示例转储:

array (
  0 => './libmysqlclient.so.16.0.0',
  1 => './libmysqlclient_r.so.16.0.0',
  2 => 
  array (
    0 => './libs/libboost_thread-mt.a',
    1 => './libs/libboost_thread-mt.so.1.38.0',
    2 => './libs/libmysql.dll',
    3 => './libs/libmysqlclient16_5.1.41-3ubuntu12_i386.deb',
  ),
  3 => 
  array (
    0 => './radio_sneaker/cl_auto.lua',
    1 => './radio_sneaker/sh_auto.lua',
    2 => './radio_sneaker/sh_coms.lua',
    3 => './radio_sneaker/sh_info.lua',
    4 => './radio_sneaker/sv_auto.lua',
    5 => './radio_sneaker/sv_hooks.lua',
  ),
  4 => './sv_auto.lua',
)

将此输出与tree在同一文件夹中运行的命令进行比较:

|   libmysqlclient.so.16.0.0
|   libmysqlclient_r.so.16.0.0
|   sv_auto.lua
|   
+---libs
|       libboost_thread-mt.a
|       libboost_thread-mt.so.1.38.0
|       libmysql.dll
|       libmysqlclient16_5.1.41-3ubuntu12_i386.deb
|       
\---radio_sneaker
        cl_auto.lua
        sh_auto.lua
        sh_coms.lua
        sh_info.lua
        sv_auto.lua
        sv_hooks.lua
于 2012-06-02T20:46:31.500 回答
1

为什么不使用joinphp中的函数来合并路径以检查它是否存在?如果不存在,则逐级检查文件夹是否存在,如果不存在,则创建并进一步移动。我的观点是,首先,创建这样一个动态结构既困难又容易搞砸。为什么不走简单的路呢?

于 2012-06-02T20:07:02.680 回答
1

想象一下,您有一个表示目录结构的数组,该数组最初是空的,将逐个填充。您需要跟踪此数组中的“当前”项并遍历目录名称。在每次迭代中,如果当前项不存在,您将在当前项下创建一个子数组,然后将当前项设置为此子数组。

这可以通过递归或迭代来完成,因为它是 PHP,所以“当前”标记需要作为参考。

考虑到这个概述,看看这个问题和那里的答案。那里的输入是字符串的形式,但这implode与您当前的情况相去甚远。

于 2012-06-02T20:13:18.097 回答
1

我会让你在你的代码中解决这个问题,但这是重要的教训。

将平面数组变成嵌套结构

$a = array(
    'dir1', 'dir2', 'file.txt'
);

$structure = array(array_pop($a));
foreach (array_reverse($a) as $dir) {
    $structure = array($dir => $structure);
}

print_r($structure);

将一个结构合并到另一个结构中

$result = array_merge_recursive($result, $structure);

只需遍历所有结构以进行合并。

于 2012-06-02T20:16:39.877 回答