Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php I';我在通过引用使用递归函数修改数组时遇到问题_Php_Arrays - Fatal编程技术网

Php I';我在通过引用使用递归函数修改数组时遇到问题

Php I';我在通过引用使用递归函数修改数组时遇到问题,php,arrays,Php,Arrays,需要一些数组引用专家的帮助。有一天我的头撞到了墙上。我需要将一系列路径转换为数据/子结构。我有来自MySQL的这些记录 +----+---------------------------------+------------------------------------------------------------------------+ | id | folder | path_string

需要一些数组引用专家的帮助。有一天我的头撞到了墙上。我需要将一系列路径转换为数据/子结构。我有来自MySQL的这些记录

+----+---------------------------------+------------------------------------------------------------------------+
| id | folder                          | path_string                                                            |
+----+---------------------------------+------------------------------------------------------------------------+
|  1 | installfolder                   | INSTALLATION PARTNERS                                                  |
|  2 | installCOIfolder                | INSTALLATION PARTNERS/DOCUMENTS/COI                                    |
|  3 | installDeliveryTicketsfolder    | INSTALLATION PARTNERS/DOCUMENTS/DELIVERY TICKETS                       |
|  4 | installPdfPackagefolder         | INSTALLATION PARTNERS/PDF INSTALLATION PACKAGE                         |
|  5 | installPunchListfolder          | INSTALLATION PARTNERS/PDF INSTALLATION PACKAGE/PDF PUNCHLIST FLOORPLAN |
|  6 | installSitePhotosfolder         | INSTALLATION PARTNERS/SITE PHOTOS                                      |
|  7 | installChangeOrdersfolder       | INSTALLATION PARTNERS/DOCUMENTS/CHANGE ORDERS                          |
|  8 | installCompletionfolder         | INSTALLATION PARTNERS/SITE PHOTOS/COMPLETION                           |
|  9 | installDamagesandWarrantyfolder | INSTALLATION PARTNERS/SITE PHOTOS/DAMAGES & WARRANTY                   |
| 10 | installMarketingfolder          | INSTALLATION PARTNERS/SITE PHOTOS/MARKETING                            |
| 11 | installProgressfolder           | INSTALLATION PARTNERS/SITE PHOTOS/MARKETING                            |
| 12 | meadowsfolder                   | MEADOWS PROJECT DOCUMENTS                                              |
| 13 | meadowsChangeOrdersfolder       | MEADOWS PROJECT DOCUMENTS/CHANGE ORDERS                                |
| 14 | meadowsPunchListfolder          | MEADOWS PROJECT DOCUMENTS/PUNCHLIST                                    |
| 15 | meadowsPunchListItemsfolder     | MEADOWS PROJECT DOCUMENTS/PUNCHLIST ITEMS                              |
+----+---------------------------------+------------------------------------------------------------------------+


DROP TABLE IF EXISTS `validation_paths`;
CREATE TABLE `validation_paths` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `folder` varchar(100) NOT NULL,
  `path_string` varchar(400) DEFAULT NULL,
  `box_id_referer` varchar(100) DEFAULT NULL,
  `title` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `validation_paths` (`id`, `folder`, `path_string`, `box_id_referer`, `title`) VALUES
(1, 'installfolder',    'INSTALLATION PARTNERS',    '', 'Installation Folder'),
(2, 'installCOIfolder', 'INSTALLATION PARTNERS/DOCUMENTS/COI',  '', 'COI Folder'),
(3, 'installDeliveryTicketsfolder', 'INSTALLATION PARTNERS/DOCUMENTS/DELIVERY TICKETS', '', 'Delivery Tickets'),
(4, 'installPdfPackagefolder',  'INSTALLATION PARTNERS/PDF INSTALLATION PACKAGE',   '', 'PDF Installation Packages'),
(5, 'installPunchListfolder',   'INSTALLATION PARTNERS/PDF INSTALLATION PACKAGE/PDF PUNCHLIST FLOORPLAN',   '', 'PDF Floorplans'),
(6, 'installSitePhotosfolder',  'INSTALLATION PARTNERS/SITE PHOTOS',    '', 'Site Photos'),
(7, 'installChangeOrdersfolder',    'INSTALLATION PARTNERS/DOCUMENTS/CHANGE ORDERS',    '', 'Change Orders'),
(8, 'installCompletionfolder',  'INSTALLATION PARTNERS/SITE PHOTOS/COMPLETION', '', 'Completion'),
(9, 'installDamagesandWarrantyfolder',  'INSTALLATION PARTNERS/SITE PHOTOS/DAMAGES & WARRANTY', '', 'Damages & Warranty'),
(10,    'installMarketingfolder',   'INSTALLATION PARTNERS/SITE PHOTOS/MARKETING',  '', 'Marketing'),
(11,    'installProgressfolder',    'INSTALLATION PARTNERS/SITE PHOTOS/MARKETING',  '', 'Progress'),
(12,    'meadowsfolder',    'MEADOWS PROJECT DOCUMENTS',    '', 'Meadows Documents'),
(13,    'meadowsChangeOrdersfolder',    'MEADOWS PROJECT DOCUMENTS/CHANGE ORDERS',  '', 'Meadows Change Orders'),
(14,    'meadowsPunchListfolder',   'MEADOWS PROJECT DOCUMENTS/PUNCHLIST',  '', 'Meadows Punchlists'),
(15,    'meadowsPunchListItemsfolder',  'MEADOWS PROJECT DOCUMENTS/PUNCHLIST ITEMS',    '', 'Meadows Punchlist Items');
我们的目标是实现这一目标

stdClass Object
(
    [children] => Array
        (
            [0] => stdClass Object
                (
                    [slug] => installfolder
                    [text] => INSTALLATION PARTNERS
                    [children] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [slug] => installCOIfolder
                                    [text] => DOCUMENTS
                                    [children] => Array
                                        (
                                            [0] => stdClass Object
                                                (
                                                    [slug] => installCOIfolder
                                                    [text] => COI
                                                    [children] => Array
                                                        (
                                                        )

                                                )

                                            [1] => stdClass Object
                                                (
                                                    [slug] => installDeliveryTicketsfolder
                                                    [text] => DELIVERY TICKETS
                                                    [children] => Array
                                                        (
                                                        )

                                                )

                                            [2] => stdClass Object
                                                (
                                                    [slug] => installChangeOrdersfolder
                                                    [text] => CHANGE ORDERS
                                                    [children] => Array
                                                        (
                                                        )

                                                )

                                        )

                                )

                            [1] => stdClass Object
                                (
                                    [slug] => installPdfPackagefolder
                                    [text] => PDF INSTALLATION PACKAGE
                                    [children] => Array
                                        (
                                            [0] => stdClass Object
                                                (
                                                    [slug] => installPunchListfolder
                                                    [text] => PDF PUNCHLIST FLOORPLAN
                                                    [children] => Array
                                                        (
                                                        )

                                                )

                                        )

                                )

                            [2] => stdClass Object
                                (
                                    [slug] => installSitePhotosfolder
                                    [text] => SITE PHOTOS
                                    [children] => Array
                                        (
                                            [0] => stdClass Object
                                                (
                                                    [slug] => installCompletionfolder
                                                    [text] => COMPLETION
                                                    [children] => Array
                                                        (
                                                        )

                                                )

                                            [1] => stdClass Object
                                                (
                                                    [slug] => installDamagesandWarrantyfolder
                                                    [text] => DAMAGES & WARRANTY
                                                    [children] => Array
                                                        (
                                                        )

                                                )

                                            [2] => stdClass Object
                                                (
                                                    [slug] => installMarketingfolder
                                                    [text] => MARKETING
                                                    [children] => Array
                                                        (
                                                        )

                                                )

                                        )

                                )

                        )

                )

            [1] => stdClass Object
                (
                    [slug] => meadowsfolder
                    [text] => MEADOWS PROJECT DOCUMENTS
                    [children] => Array
                        (
                            [0] => stdClass Object
                                (
                                    [slug] => meadowsChangeOrdersfolder
                                    [text] => CHANGE ORDERS
                                    [children] => Array
                                        (
                                        )

                                )

                            [1] => stdClass Object
                                (
                                    [slug] => meadowsPunchListfolder
                                    [text] => PUNCHLIST
                                    [children] => Array
                                        (
                                        )

                                )

                            [2] => stdClass Object
                                (
                                    [slug] => meadowsPunchListItemsfolder
                                    [text] => PUNCHLIST ITEMS
                                    [children] => Array
                                        (
                                        )

                                )

                        )

                )

        )

)
现在我要做的是。我使用两个递归函数合并这个结构。这是第一个

function buildTree(array &$array, $parents, $value, $glue = '/')
{
    if (!is_array($parents)) {
        $parents = explode($glue, (string) $parents);
    }

    $ref = &$array;

    foreach ($parents as $key => $parent) {
        if (isset($ref) && !is_array($ref)) {
            $ref = [];
        }

        $ref = &$ref[$parent];
    }

    $ref = $value;
}

$query = "SELECT * FROM validation_paths";

$results = $db->query($query);

$tree = array();

if (!empty($results)){ 
    foreach ($results as $folder){
        buildTree($tree,$folder['path_string'] . '/slug',$folder['folder']);
        buildTree($tree,$folder['path_string'] . '/text',$folder['path_string']);
    }
}   

pruneTree($tree);
echo '<pre>';
print_r($tree);
然后我被绊倒了。我使用这个递归函数根据自己的需要修改这个结构,但没有得到好的结果

下面是函数

Array
(
    [INSTALLATION PARTNERS] => Array
        (
            [slug] => installfolder
            [text] => INSTALLATION PARTNERS
            [DOCUMENTS] => Array
                (
                    [COI] => Array
                        (
                            [slug] => installCOIfolder
                            [text] => COI
                            [children] => Array
                                (
                                )

                        )

                    [DELIVERY TICKETS] => Array
                        (
                            [slug] => installDeliveryTicketsfolder
                            [text] => DELIVERY TICKETS
                            [children] => Array
                                (
                                )

                        )

                    [CHANGE ORDERS] => Array
                        (
                            [slug] => installChangeOrdersfolder
                            [text] => CHANGE ORDERS
                            [children] => Array
                                (
                                )

                        )

                    [slug] => installCOIfolder
                    [text] => DOCUMENTS
                    [children] => Array
                        (
                        )

                )

            [PDF INSTALLATION PACKAGE] => Array
                (
                    [slug] => installPdfPackagefolder
                    [text] => PDF INSTALLATION PACKAGE
                    [PDF PUNCHLIST FLOORPLAN] => Array
                        (
                            [slug] => installPunchListfolder
                            [text] => PDF PUNCHLIST FLOORPLAN
                            [children] => Array
                                (
                                )

                        )

                    [children] => Array
                        (
                        )

                )

            [SITE PHOTOS] => Array
                (
                    [slug] => installSitePhotosfolder
                    [text] => SITE PHOTOS
                    [COMPLETION] => Array
                        (
                            [slug] => installCompletionfolder
                            [text] => COMPLETION
                            [children] => Array
                                (
                                )

                        )

                    [DAMAGES & WARRANTY] => Array
                        (
                            [slug] => installDamagesandWarrantyfolder
                            [text] => DAMAGES & WARRANTY
                            [children] => Array
                                (
                                )

                        )

                    [MARKETING] => Array
                        (
                            [slug] => installProgressfolder
                            [text] => MARKETING
                            [children] => Array
                                (
                                )

                        )

                    [children] => Array
                        (
                        )

                )

            [children] => Array
                (
                )

        )

    [MEADOWS PROJECT DOCUMENTS] => Array
        (
            [slug] => meadowsfolder
            [text] => MEADOWS PROJECT DOCUMENTS
            [CHANGE ORDERS] => Array
                (
                    [slug] => meadowsChangeOrdersfolder
                    [text] => CHANGE ORDERS
                    [children] => Array
                        (
                        )

                )

            [PUNCHLIST] => Array
                (
                    [slug] => meadowsPunchListfolder
                    [text] => PUNCHLIST
                    [children] => Array
                        (
                        )

                )

            [PUNCHLIST ITEMS] => Array
                (
                    [slug] => meadowsPunchListItemsfolder
                    [text] => PUNCHLIST ITEMS
                    [children] => Array
                        (
                        )

                )

            [children] => Array
                (
                )

        )

    [slug] => installfolder
    [text] => 
    [children] => Array
        (
        )

)
我从中得到

function set_nested_array_value(&$array, $path, &$value, $delimiter = '/') {
    $pathParts = explode($delimiter, $path);

    $current = &$array;
    foreach($pathParts as $key) {
        $current = &$current[$key];
    }

    $backup = $current;
    $current = $value;

    return $backup;
}

谁能给我一个正确方向的提示?谢谢。

首先,有其他方法可以做到这一点,但为了保持您的工作流程,我将修改
buildTree
函数来存储所有需要的数据。为此,您可以使用以下答案:

现在您可以调用此函数并使用该值存储slug,在本例中,我使用
['folder'=>$path['folder']]
,因此现在您有:

function pruneTree( $array){
    $result = []; $i = 0;

    foreach($array as $key=>$node){
       $r = [];
       // set the slug if it exists
        if(isset( $node['folder'])){
            $r['slug'] = $node['folder'];
            unset($node['folder']);
        }
        $r['text']  = $key;
        // set the children through recursion
        $r['children'] = pruneTree($node);

        // when the node does not have slug (ie: DOCUMENTS)
        // set the slug of the first child - to match expected results.
        if(!isset($r['slug']) && isset($r['children'][0])){
            $r['slug'] =  $r['children'][0]->slug;
        }
        // transform to object - to match expected results.
        $result[$i] =(object) $r;  
        $i++;
    }

    return $result;
}
然后修改
pruneTree
以创建stdClass对象及其子对象:

$r = [
    'children' => pruneTree(buildTree($results))
];
print_r((object)$r); 
现在,为了符合您的预期结果,您可以执行以下操作:

function buildTree($data) {
    $tree = new StdClass;
    $index = [];
    foreach ($data as $item) {
        $node = $tree;
        $path = '';
        foreach (explode('/', $item['path_string']) as $segment) {
            $path .= empty($path) ? $segment : '/' . $segment;
            if (!isset($index[$path])) {
                $index[$path] = new stdClass;
                $index[$path]->slug = $item['folder'];
                $index[$path]->text = $segment;
                $index[$path]->children = [];
                $node->children[] = $index[$path]
            }
            $node = $index[$path];
        }
    }

    return $tree;
}

以下是

因为对象本身是作为引用传递的,所以您只需要使用路径段(关系数据)找到正确的对象。最简单的方法是使用这些路径作为索引,您可以在后续迭代中引用它们。尝试此功能:


在您的示例中,没有安装伙伴/文档的数据,因此它将保持为空节点(仅限子节点)。如果不是错误,请提供一些信息,因为我不知道如何解析其属性,以便与预期结果相匹配。

谢谢您的回答,但实际上我已经开始了。没有将子项替换为路径段名称。我使用您的sql创建了表,并从中运行代码以获得您期望的结果。您是否更改了表或查询?嗨,Michael,很抱歉造成误导,它工作得很好!非常感谢。我给迈克尔写信了吗?对不起,米歇尔。我看到的唯一问题是成员的顺序在最后是“slug”,这可能会触发格式错误的json。谢谢。@www.data很乐意帮忙。是的,我的回答不包括所有情况或您可能有的任何其他要求,只是一种方法。随意修改:)非常接近!仍然在计算文档条目异常,并将子节点添加到all,即使是空的。如果这可以在一个功能中实现,那么这个答案将非常棒!非常感谢。非常感谢你的兄弟,你的方法真的很熟练!下面是一个小的编辑,它可以在一个递归函数中工作。你们应该得到一个捐款人,万分感谢。@www.data我将把它作为答案。但要小心,因为这取决于数据库中的记录顺序(这是解决空
文档
节点的唯一方法)。考虑一下进入+1,注意到对象是通过引用传递的,并且在一个函数中完成了所有操作,很好地完成了。
function pruneTree( $array){
    $result = []; $i = 0;

    foreach($array as $key=>$node){
       $r = [];
       // set the slug if it exists
        if(isset( $node['folder'])){
            $r['slug'] = $node['folder'];
            unset($node['folder']);
        }
        $r['text']  = $key;
        // set the children through recursion
        $r['children'] = pruneTree($node);

        // when the node does not have slug (ie: DOCUMENTS)
        // set the slug of the first child - to match expected results.
        if(!isset($r['slug']) && isset($r['children'][0])){
            $r['slug'] =  $r['children'][0]->slug;
        }
        // transform to object - to match expected results.
        $result[$i] =(object) $r;  
        $i++;
    }

    return $result;
}
$r = [
    'children' => pruneTree(buildTree($results))
];
print_r((object)$r); 
function buildTree($data) {
    $tree = new StdClass;
    $index = [];
    foreach ($data as $item) {
        $node = $tree;
        $path = '';
        foreach (explode('/', $item['path_string']) as $segment) {
            $path .= empty($path) ? $segment : '/' . $segment;
            if (!isset($index[$path])) {
                $index[$path] = new stdClass;
                $index[$path]->slug = $item['folder'];
                $index[$path]->text = $segment;
                $index[$path]->children = [];
                $node->children[] = $index[$path]
            }
            $node = $index[$path];
        }
    }

    return $tree;
}