我有一些文件列表数组,其元素数量超过100s我需要转换为树数组并将它们插入数据库并在调用时返回树以获取json api目录系统 我花了一个星期尝试不同的算法,所有这些都在某些时候失败了。 这是数组:
$files[] = array('dir1/dir2/dir3/file1.mkv', 44444);
$files[] = array('dir1/dir2/dir3/file2.mkv', 44444);
$files[] = array('dir1/dir2/file1.mkv', 44444);
$files[] = array('dir1/dir2/file2.txt', 11111);
$files[] = array('dir1/file1.exe', 22222);
$files[] = array('dir1/file2.exe', 22222);
$files[] = array('file1.rar', 3333);
第一个元素是文件路径,第二个元素是filesize。 这些文件不存在于此服务器上,它们位于不同的服务器上,这是api服务器。 我需要将它转换为嵌套的树数组,如下所示:
Array
(
[dir1] => Array
(
[dir2] => Array
(
[dir3] => Array
(
[0] => Array
(
[name] => file1.mkv
[size] => 44444
)
[1] => Array
(
[name] => file2.mkv
[size] => 44444
)
)
[0] => Array
(
[name] => file1.mkv
[size] => 44444
)
[1] => Array
(
[name] => file2.txt
[size] => 11111
)
)
[0] => Array
(
[name] => file1.exe
[size] => 22222
)
[1] => Array
(
[name] => file2.exe
[size] => 22222
)
)
[0] => Array
(
[name] => file1.rar
[size] => 3333
)
)
我写了一些代码,但它只上升到第二级(dir2),然后在第三级(dir3),它无法按预期执行。
代码:
foreach ($files as $file)
{
$info = pathinfo($file[0]);
if ($info['dirname'] != '.')
{
if (strpos($info['dirname'], '/') !== false)
{
$dirs[pathinfo($info['dirname'])['dirname']][pathinfo($info['dirname'])['basename']][] = array('name' => $info['basename'], 'size' => $file[1]);
}
else
{
$dirs[$info['dirname']][] = array('name' => $info['basename'], 'size' => $file[1]);
}
}
else
{
$dirs[] = array('name' => $info['basename'], 'size' => $file[1]);
}
}
如果从文件列表数组中删除dir3级别,此代码会返回数组,但是如果存在dir3,则会给出:
Array
(
[dir1/dir2] => Array
(
[dir3] => Array
(
[0] => Array
(
[name] => file1.mkv
[size] => 44444
)
[1] => Array
(
[name] => file2.mkv
[size] => 44444
)
)
)
[dir1] => Array
(
[dir2] => Array
(
[0] => Array
(
[name] => file1.mkv
[size] => 44444
)
[1] => Array
(
[name] => file2.txt
[size] => 11111
)
)
[0] => Array
(
[name] => file1.exe
[size] => 22222
)
[1] => Array
(
[name] => file2.exe
[size] => 22222
)
)
[0] => Array
(
[name] => file1.rar
[size] => 3333
)
)
这个[dir1 / dir2]是问题,我需要它是一个完美的树,所以我可以通过它重复并将记录插入数据库。
答案 0 :(得分:0)
由于您事先不知道树深度,因此无法使用if / else循环进行管理。这是一个需要递归的用例。
<?php
function scanpath($path) {
$myscan = scandir($path);
$tree=[];
foreach($myscan as $entry) {
//echo '<br>'.$entry;
if($entry==='.' || $entry ==='..') {
// do nothing
} else if(is_dir($path.'/'.$entry)) {
// this is a folder, I will recurse
$tree[$entry] = scanpath($path.'/'.$entry);
} else {
// this is a file or link. Value is file size
$tree[$entry] = filesize($path.'/'.$entry);
}
}
return $tree;
}
$scanresult=scanpath(__DIR__);
echo '<pre>';
print_r($scanresult);
echo '</pre>';
你看,我在一个给定的路径上调用一个函数。对于该路径上的每个条目我
您需要修改我的代码以满足您的需求。我可以告诉你的“是文件或链接”的情况有不同的格式。
编辑:由于没有真正的文件结构要扫描,而是你有一个路径数组,这就是我带来的解决方案
<?php
$thefiles=[];
$thefiles[] = array('dir1/dir2/dir3/file1.mkv', 44444);
$thefiles[] = array('dir1/dir2/dir3/file2.mkv', 44444);
$thefiles[] = array('dir1/dir2/file1.mkv', 44444);
$thefiles[] = array('dir1/dir2/file2.txt', 11111);
$thefiles[] = array('dir1/dir4/file5.mkv', 22444);
$thefiles[] = array('dir1/dir4/file6.txt', 15111);
$thefiles[] = array('dir1/file1.exe', 22222);
$thefiles[] = array('dir1/file2.exe', 22222);
$thefiles[] = array('file1.rar', 3333);
$filearray=[];
function scanpath($patharray,$filesize) {
$tree=[];
if(count($patharray)===1) {
$filename=array_pop($patharray);
$tree[] = ['name'=>$filename, 'size'=>$filesize];
} else {
$pathpart = array_pop($patharray);
$tree[$pathpart] = scanpath($patharray,$filesize);
}
return $tree;
}
foreach($thefiles as $fileentry) {
$patharray=array_reverse(explode('/',$fileentry[0]));
$thisarray = scanpath($patharray,$fileentry[1]);
$filearray= array_merge_recursive($filearray,$thisarray);
}
echo '<pre>';
print_r($filearray);
echo '</pre>';
我使用斜杠作为分隔符展开每个路径,然后在路径上逐个文件夹递归,直到我到达最后一部分,递归以文件名和大小结束。
答案 1 :(得分:0)
这是我的方式
$path='E:\conf\transfer';
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
$tree_array=array();
foreach($objects as $name => $object){
if(in_array($object->getFilename(),array('..','.')) || is_dir($object->getPathname()))
{
continue;
}
$path_info=explode(DIRECTORY_SEPARATOR ,$object->getPathname());
$file_name=array_pop($path_info);
$path_info="['".implode("']['",$path_info)."']";
$code='$tree_array'.$path_info.'[] = '.'\''.$file_name.'\';';
eval($code);
}
var_dump($tree_array);
&#13;