使用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