PHP文件结构数组到json字符串仅正确显示第一个文件

PHP文件结构数组到json字符串仅正确显示第一个文件,php,arrays,json,cakephp,Php,Arrays,Json,Cakephp,我有一段代码可以扫描给定的目录并将内容输出到一个数组中,下面是一个示例数组 Array ( [0] => docker-vs-vagrant.png [floor] => Array ( [moretesting] => Array ( [0] => Webserver_requests_graph.jpg )

我有一段代码可以扫描给定的目录并将内容输出到一个数组中,下面是一个示例数组

Array
(
    [0] => docker-vs-vagrant.png
    [floor] => Array
        (
            [moretesting] => Array
                (
                    [0] => Webserver_requests_graph.jpg
                )

        )

    [plans] => Array
        (
            [0] => Screen Shot 2017-10-09 at 7.08.52 pm.png
        )

    [1] => screenshot.png
    [screenshots] => Array
        (
        )

    [test] => Array
        (
            [0] => Screen_Shot_2017-10-09_at_4_52_32_pm.png
        )

    [test2] => Array
        (
            [0] => testScreen Shot 2017-10-09 at 7.08.52 pm.png
        )

)
如您所知,标有键[0]和[1]的文件位于根目录中,其他所有内容都组织到文件夹结构中

我用来生成这个数组的代码如下:

function dirToArray($dir) {
    $contents = array();

    foreach (scandir($dir) as $node) {
        if ($node == '.' || $node == '..') continue;

        if (is_dir($dir . '/' . $node)) {
            $contents[$node] = $this->dirToArray($dir . '/' . $node);
        } else {
            $contents[] = $node;
        }
    }

    return $contents;
}
function flatArrayToJsonString($flatArray)
{
    $arrayId = 1;
    $final_array = [[0, '/', '/', false]];

    foreach ($flatArray as $key => $val) {
        if ($key == '0') {
            $final_array[] = [$arrayId, '/' . $val, $val, true];
            $arrayId++;
        } else {
            $exploded_key = explode('.', $key);
            foreach ($exploded_key as $k => $v) {
                if ($v == '0') {
                    $dots = '.. ';
                    for ($i = 0; $i < count(array_slice($exploded_key, 0, $k)); $i++) {
                        $dots .= '.. ';
                    }
                    $final_array[] = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k)) . '/' . $val, $dots . $val, true];
                    $arrayId++;
                } else {
                    $dots = '.. ';
                    for ($i = 0; $i < count(array_slice($exploded_key, 0, $k)); $i++) {
                        $dots .= '.. ';
                    }
                    $final_array[] = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k + 1)), $dots . $v, false];
                    $arrayId++;
                }
            }
        }
    }

    return json_encode($final_array);
}
[
    [0,"\/","\/",false],
    [1,"\/docker-vs-vagrant.png","docker-vs-vagrant.png",true],
    [2,"\/floor",".. floor",false],
    [3,"\/floor\/moretesting",".. .. moretesting",false],
    [4,"\/floor\/moretesting\/Webserver_requests_graph.jpg",".. .. .. Webserver_requests_graph.jpg",true],
    [5,"\/plans",".. plans",false],
    [6,"\/plans\/Screen Shot 2017-10-09 at 7.08.52 pm.png",".. .. Screen Shot 2017-10-09 at 7.08.52 pm.png",true],
    [7,"\/1",".. 1",false],
    [8,"\/test",".. test",false],
    [9,"\/test\/Screen_Shot_2017-10-09_at_4_52_32_pm.png",".. .. Screen_Shot_2017-10-09_at_4_52_32_pm.png",true],
    [10,"\/test2",".. test2",false],
    [11,"\/test2\/testScreen Shot 2017-10-09 at 7.08.52 pm.png",".. .. testScreen Shot 2017-10-09 at 7.08.52 pm.png",true]
]
[id, fullpath, displayname, leaf]
在这之后,我使用一个内置的cakephp函数来展平数组,使其看起来如下所示

Array
(
    [0] => docker-vs-vagrant.png
    [floor.moretesting.0] => Webserver_requests_graph.jpg
    [plans.0] => Screen Shot 2017-10-09 at 7.08.52 pm.png
    [1] => screenshot.png
    [test.0] => Screen_Shot_2017-10-09_at_4_52_32_pm.png
    [test2.0] => testScreen Shot 2017-10-09 at 7.08.52 pm.png
)
之后,我需要将其格式化为json,以便我的javascript api可以读取,实现这一点的函数如下

function dirToArray($dir) {
    $contents = array();

    foreach (scandir($dir) as $node) {
        if ($node == '.' || $node == '..') continue;

        if (is_dir($dir . '/' . $node)) {
            $contents[$node] = $this->dirToArray($dir . '/' . $node);
        } else {
            $contents[] = $node;
        }
    }

    return $contents;
}
function flatArrayToJsonString($flatArray)
{
    $arrayId = 1;
    $final_array = [[0, '/', '/', false]];

    foreach ($flatArray as $key => $val) {
        if ($key == '0') {
            $final_array[] = [$arrayId, '/' . $val, $val, true];
            $arrayId++;
        } else {
            $exploded_key = explode('.', $key);
            foreach ($exploded_key as $k => $v) {
                if ($v == '0') {
                    $dots = '.. ';
                    for ($i = 0; $i < count(array_slice($exploded_key, 0, $k)); $i++) {
                        $dots .= '.. ';
                    }
                    $final_array[] = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k)) . '/' . $val, $dots . $val, true];
                    $arrayId++;
                } else {
                    $dots = '.. ';
                    for ($i = 0; $i < count(array_slice($exploded_key, 0, $k)); $i++) {
                        $dots .= '.. ';
                    }
                    $final_array[] = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k + 1)), $dots . $v, false];
                    $arrayId++;
                }
            }
        }
    }

    return json_encode($final_array);
}
[
    [0,"\/","\/",false],
    [1,"\/docker-vs-vagrant.png","docker-vs-vagrant.png",true],
    [2,"\/floor",".. floor",false],
    [3,"\/floor\/moretesting",".. .. moretesting",false],
    [4,"\/floor\/moretesting\/Webserver_requests_graph.jpg",".. .. .. Webserver_requests_graph.jpg",true],
    [5,"\/plans",".. plans",false],
    [6,"\/plans\/Screen Shot 2017-10-09 at 7.08.52 pm.png",".. .. Screen Shot 2017-10-09 at 7.08.52 pm.png",true],
    [7,"\/1",".. 1",false],
    [8,"\/test",".. test",false],
    [9,"\/test\/Screen_Shot_2017-10-09_at_4_52_32_pm.png",".. .. Screen_Shot_2017-10-09_at_4_52_32_pm.png",true],
    [10,"\/test2",".. test2",false],
    [11,"\/test2\/testScreen Shot 2017-10-09 at 7.08.52 pm.png",".. .. testScreen Shot 2017-10-09 at 7.08.52 pm.png",true]
]
[id, fullpath, displayname, leaf]
只有在根目录或任何子目录中有1个文件时,这才是完美的

但一旦添加了另一个文件,它就会中断

您可以看到以下值:

[1] => screenshot.png
在错误的位置,并且在最终输出中被破坏,显示为

[7,"\/1",".. 1",false],
当我试图显示一个层次结构时,应该这样显示

[1,"\/docker-vs-vagrant.png","docker-vs-vagrant.png",true],
[2,"\/screenshot.png","screenshot.png",true],
最终输出的描述如下:

function dirToArray($dir) {
    $contents = array();

    foreach (scandir($dir) as $node) {
        if ($node == '.' || $node == '..') continue;

        if (is_dir($dir . '/' . $node)) {
            $contents[$node] = $this->dirToArray($dir . '/' . $node);
        } else {
            $contents[] = $node;
        }
    }

    return $contents;
}
function flatArrayToJsonString($flatArray)
{
    $arrayId = 1;
    $final_array = [[0, '/', '/', false]];

    foreach ($flatArray as $key => $val) {
        if ($key == '0') {
            $final_array[] = [$arrayId, '/' . $val, $val, true];
            $arrayId++;
        } else {
            $exploded_key = explode('.', $key);
            foreach ($exploded_key as $k => $v) {
                if ($v == '0') {
                    $dots = '.. ';
                    for ($i = 0; $i < count(array_slice($exploded_key, 0, $k)); $i++) {
                        $dots .= '.. ';
                    }
                    $final_array[] = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k)) . '/' . $val, $dots . $val, true];
                    $arrayId++;
                } else {
                    $dots = '.. ';
                    for ($i = 0; $i < count(array_slice($exploded_key, 0, $k)); $i++) {
                        $dots .= '.. ';
                    }
                    $final_array[] = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k + 1)), $dots . $v, false];
                    $arrayId++;
                }
            }
        }
    }

    return json_encode($final_array);
}
[
    [0,"\/","\/",false],
    [1,"\/docker-vs-vagrant.png","docker-vs-vagrant.png",true],
    [2,"\/floor",".. floor",false],
    [3,"\/floor\/moretesting",".. .. moretesting",false],
    [4,"\/floor\/moretesting\/Webserver_requests_graph.jpg",".. .. .. Webserver_requests_graph.jpg",true],
    [5,"\/plans",".. plans",false],
    [6,"\/plans\/Screen Shot 2017-10-09 at 7.08.52 pm.png",".. .. Screen Shot 2017-10-09 at 7.08.52 pm.png",true],
    [7,"\/1",".. 1",false],
    [8,"\/test",".. test",false],
    [9,"\/test\/Screen_Shot_2017-10-09_at_4_52_32_pm.png",".. .. Screen_Shot_2017-10-09_at_4_52_32_pm.png",true],
    [10,"\/test2",".. test2",false],
    [11,"\/test2\/testScreen Shot 2017-10-09 at 7.08.52 pm.png",".. .. testScreen Shot 2017-10-09 at 7.08.52 pm.png",true]
]
[id, fullpath, displayname, leaf]
其中leaf表示它是文件还是目录

我很抱歉这是一个如此大的帖子,但我不知道如何着手解决这个问题


如果有任何帮助,我们将不胜感激。

您的代码的问题在于,它只准备处理每个文件夹中的一个文件。它不仅在根文件夹中有多个文件时会断开,而且在子文件夹中也会断开

如果您的任何文件夹包含名为“0”的子文件夹,它也将中断

以下代码修复了这些问题:

function flatArrayToJsonString($flatArray)
{
    $arrayId = 1;
    $final_array = [[0, '/', '/', false]];
    ksort($flatArray, SORT_STRING);  // Sort the flat array by keys

    foreach ($flatArray as $key => $val) {
        $exploded_key = explode('.', $key);
        foreach ($exploded_key as $k => $v) {
            if ($k == sizeof($exploded_key)-1) { // last element of exploded key is always a file
                $dots = '.. ';
                for ($i = 0; $i < count(array_slice($exploded_key, 0, $k)); $i++) {
                    $dots .= '.. ';
                }
                $final_array[] = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k)) . '/' . $val, $dots . $val, true];
                $arrayId++;
            } else {
                $dots = '.. ';
                for ($i = 0; $i < count(array_slice($exploded_key, 0, $k)); $i++) {
                    $dots .= '.. ';
                }
                $final_array[] = [$arrayId, '/' . join('/', array_slice($exploded_key, 0, $k + 1)), $dots . $v, false];
                $arrayId++;
            }
        }
    }

    return json_encode($final_array);
}
函数flatArrayToJsonString($flatArray)
{
$arrayId=1;
$final_数组=[[0,'/','/',false]];
ksort($flatary,SORT_STRING);//按键对平面数组进行排序
foreach($key=>$val的平面阵列){
$exploded_key=exploded('.',$key);
foreach($k=>v){
如果($k==sizeof($exploded_key)-1){//分解键的最后一个元素始终是一个文件
$dots='…';
对于($i=0;$i
我已尝试尽可能少地修改您的代码以使其正常工作。然而,有更好的方法来解决你的问题

请注意,您的代码从一开始就是有缺陷的。使用
Hash::flatte()
展平数组不是一个好主意,因为如果文件夹名包含点,则会使代码中断。您可以使用不同的分隔符(例如,您知道文件系统不会使用的字符或字符串)。然而,使用关联数组或对象总是更好的


您应该探索其他选项,例如在文件系统上迭代时一次完成所有操作(如@ndm在注释中所建议的)。

您是否特别需要展平阵列?因为如果不是的话,你可以这样做:

function flatArrayToJsonString($flatArray)
{
    return json_encode($flatArray); //returns string
}
然后在javascript中进行适当的格式化

但是,我不建议展平原始数组,因为在使用cakephp展平它之前,它在原始数组的布局中具有目录结构/层次结构


编辑:在很多情况下,拥有一个id也没有什么意义,因为可以添加或删除文件和目录,从而使php最初发送的任何id无效。也许你应该重新审视一下你目前解决这个问题的方法

为什么不在文件系统上迭代时直接构建最终的数组结构,为什么所有这些步骤都在这两者之间?@ndm我不知道如何去做你提到的事情。。。我发布的代码是拼凑在一起的,它很难让我理解为isHey,这类作品。。。但是id为7的文件应该在id为1的文件下,因为它们都在根目录中。。。有没有一种方法可以像层次结构一样对它们进行分组?您可以在处理数组之前对其进行排序。这可以通过“ksort($flatArray,SORT_STRING)”来完成。我已经编辑了代码来添加这一行。好的,这非常有效。。。我知道代码不好,我以后会重构,但我只需要尽快把它弄出来。。。非常感谢你的帮助,我真的很感激!