我有一个包含在数组中的数据,就像这样,
$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'];
}
如何为每个存在的目录动态创建数组并添加所需的信息,同时记住目录结构可能是任何级别的深度?
感谢您抽出时间阅读我相当长的问题,感谢任何人给予我的任何帮助。
答案 0 :(得分: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;
}
此函数首先打开set $dir
文件夹并扫描文件列表,将每个找到的文件添加到数组中,在扫描文件夹后,return
ed作为函数的返回值
当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
答案 1 :(得分:1)
为什么不在php中使用join
函数来合并路径以检查它是否存在?如果没有,则逐级检查文件夹是否存在,如果不存在,则创建并进一步移动。我的观点是,创建这样一个动态结构首先是困难而且容易搞砸。为什么不轻松一点?
答案 2 :(得分:1)
想象一下,你有一个表示目录结构的数组,该数组最初是空的,将逐个填充。您需要跟踪此数组中的“当前”项并迭代目录名称。在每次迭代中,如果当前项尚不存在,则在当前项下创建一个子数组,然后将当前项设置为该子数组。
这可以通过递归或迭代来完成,因为它是PHP,“当前”标记需要作为参考。
考虑到这一概述,请查看this question及其答案。输入以字符串的形式出现,但距离当前情况只有implode
。
答案 3 :(得分: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);
只需迭代所有结构进行合并。