使用PHP从另一个数组动态构建多维数组?

使用PHP从另一个数组动态构建多维数组?,php,arrays,dynamic,creation,Php,Arrays,Dynamic,Creation,我的数据包含在一个数组中,就像这样 $file['info']['files'] = array( [0] => array( 'length' => (int), 'path' => array ( [0] => 'file.txt', ), ), [1] => array( 'length' => (int), 'p

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

$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']
数组可以包含任意数量的元素。每个
$file['info']['files']
数组中包含的
路径
数组就是我遇到问题的地方

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

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
        }
    }
}
在向阵列添加目录时,我遇到了麻烦。我可以手动操作,每次只检查目录的数组是否存在,如果不创建它,并且如果它确实存在,则添加到它中,那么每次只检查这么多目录。我在下面的代码中尝试了这一点,但它只深入一个目录(代码位于上面的
//buildarray STRUCTURE
位置)

我如何为存在的每个目录动态创建数组并添加所需的信息,记住目录结构可以是任意深度的


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

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

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

这可以通过递归或迭代来完成,因为它是PHP,“当前”标记需要是一个引用


记住这个概述,看看这里的答案。那里的输入是以字符串的形式存在的,但这只是一个
内爆,与您当前的情况相去甚远。

我会让您将此融入到您的代码中,但这里有重要的经验教训

将平面阵列转换为嵌套结构

$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);

只需迭代合并的所有结构。

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

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;
}
此函数首先打开set
$dir
文件夹并扫描文件列表,将找到的每个文件添加到数组中,在扫描文件夹后,
返回
作为函数的返回值

scandir()
结果(文件夹中的文件和文件夹列表)的条目实际上是一个文件夹时,就会出现扭曲。如果发生这种情况,将从函数的内部递归调用该函数(请参见行
$names[]=get_contents\u 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',
)
将此输出与在同一文件夹上运行的
命令进行比较:

|   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

你熟悉递归吗?这种问题(当你不知道嵌套有多少层时)可以通过递归函数来解决。RecurSrive是调用自身的函数
|   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