php yalinqo - 迭代结果

时间:2016-03-28 20:33:22

标签: php foreach menu yalinqo

我有一个表格结构,如下所示,其中item_id - > 1,2是主菜单项...而item_id - > 3,4是1的子项,可以由parent_id确定

enter image description here

我正在使用以下代码来获取并遍历此结果。并在UI上正确构建菜单。

直到我使用foreach循环' foreach-1'一切正常。结果是

  

1-BAGS()... 2-ACCESSORIES()......

但是当我添加foreach循环' foreach-2'。结果不会显示(2-Accessories),如下所示

  

1-BAGS(3,4,)......

正如您所看到的,我正在使用yalinqo库从结果集中获取数据。而对于yalinqo在www上的帮助却很少。

是否有一些隐藏的诅咒会造成问题? 或者yalinqo查询的形成方式有问题吗?

如果您曾在yalinqo工作,请在这里帮助我。因为我更像是一个.net用户,对php的经验非常少。

我在这里只发布部分代码:

use \YaLinqo\Enumerable as E;

...

if ($connection)
    {
         $result = mysqli_query($connection, "CALL fetch_main_menu") or die("Query fail: " . mysqli_error());

         $result_data =  E::from ($result) ;

         $top_menu = E::from ($result_data ) 
         ->where (function($item){return $item["parent_id"]==null;}) 
         ->select (function ($item){return $item;});

         //foreach - 1
         foreach ($top_menu as $i )
         {
             $item_id = $i["id"];
             $item_name = $i["name"];

             echo $item_id . '-' . $item_name ;

             //fetch subitems
             $sub_menu = E::from ($result_data) 
             ->where (function($item){global $item_id; return $item["parent_id"] != null && $item["parent_id"] == $item_id;})
             ->select (function ($item){return $item;});

             echo '(';

             //foreach - 2
             foreach($sub_menu as $sub_i)
             {
                 echo $sub_i["id"] . ',';
             }

             unset($sub_menu);

             echo ')  ... ';
         }
    }

P.S。:如果有菜单栏结构,我很乐意使用另一种更高效的工作。

1 个答案:

答案 0 :(得分:3)

如果您对YaLinqo有任何疑问,请不要犹豫直接询问我或在YaLinqo's issue tracker中创建支持问题。

您的代码在不必要的情况下更复杂,并且在必要时不够复杂。 :)

  1. select (function ($item){return $item;})是不必要的,它什么都不做,只是where就足够了(如果你使用的是函数语法,这同样适用于.NET LINQ):

    $top_menu = E::from ($result_data) 
        ->where (function($item){return $item["parent_id"]==null;});
    
  2. 您可以将global语句添加到匿名函数中,而不是使用use

    $sub_menu = E::from ($result_data) 
        ->where (function($item) use($item_id) {
            return $item["parent_id"] != null && $item["parent_id"] == $item_id;
        });
    

    与.NET不同,需要明确捕获变量。此外,新代码中应避免使用global

  3. 您的模型建议使用递归函数,但您的代码仅支持2个级别。如果您只需要两个级别,则只需一个查询就可以轻松完成。

  4. 我们假设我们已经有了一个数组:

    $items = [
        [ 'id' => 1, 'name' => "BAGS", 'parent_id' => null ],
        [ 'id' => 2, 'name' => "ACCESSORIES", 'parent_id' => null ],
        [ 'id' => 3, 'name' => "Messenger", 'parent_id' => 1 ],
        [ 'id' => 4, 'name' => "Sling", 'parent_id' => 1 ],
        [ 'id' => 5, 'name' => "Earrings", 'parent_id' => 2 ],
        [ 'id' => 6, 'name' => "Clip", 'parent_id' => 2 ],
    ];
    

    构建菜单层次结构可以这样做:

    $menu = from($items)
        ->where(function ($ti) {
            return $ti['parent_id'] === null;
        })
        ->select(function ($ti) use ($items) {
            return [
                'menu' => $ti,
                'items' => from($items)
                    ->where(function ($si) use ($ti) {
                        return $si['parent_id'] === $ti['id'];
                    })
            ];
        });
    
    print_r($menu->toArrayDeep());
    

    输出:

    Array
    (
        [0] => Array
            (
                [menu] => Array
                    (
                        [id] => 1
                        [name] => BAGS
                        [parent_id] => 
                    )
                [items] => Array
                    (
                        [2] => Array
                            (
                                [id] => 3
                                [name] => Messenger
                                [parent_id] => 1
                            )
                        [3] => Array
                            (
                                [id] => 4
                                [name] => Sling
                                [parent_id] => 1
                            )
                    )
            )
        [1] => Array
            (
                [menu] => Array
                    (
                        [id] => 2
                        [name] => ACCESSORIES
                        [parent_id] => 
                    )
                [items] => Array
                    (
                        [4] => Array
                            (
                                [id] => 5
                                [name] => Earrings
                                [parent_id] => 2
                            )
                        [5] => Array
                            (
                                [id] => 6
                                [name] => Clip
                                [parent_id] => 2
                            )
                    )
            )
    )
    

    或者,如果您只需要一个字符串:

    $menustring = from($items)
        ->where(function ($ti) {
            return $ti['parent_id'] === null;
        })
        ->select(function ($ti) use ($items) {
            return "{$ti['id']}-{$ti['name']}("
            . from($items)
                ->where(function ($si) use ($ti) {
                    return $si['parent_id'] === $ti['id'];
                })
                ->toString(',', function ($si) {
                    return "{$si['id']}-{$si['name']}";
                })
            . ")";
        })
        ->toString(';');
    
    echo($menustring);
    

    输出:

    1-BAGS(3-Messenger,4-Sling);2-ACCESSORIES(5-Earrings,6-Clip)
    

    最后,一个递归函数适用于任何级别的嵌套:

    function get_menu_with_subitems ($items, $item)
    {
        $subitems = from($items)
            ->where(function ($i) use ($item) {
                return $i['parent_id'] === $item['id'];
            })
            ->select(function ($i) use ($items) {
                return get_menu_with_subitems($items, $i);
            })
            ->toList();
        return [
            'id' => $item['id'],
            'name' => $item['name'],
            'items' => count($subitems) > 0 ? $subitems : null,
        ];
    }
    
    $root = [ 'id' => null, 'name' => 'Root' ];
    $menu = get_menu_with_subitems($items, $root)['items'];
    print_r($menu);
    

    输出:

    (
        [0] => Array
            (
                [id] => 1
                [name] => BAGS
                [items] => Array
                    (
                        [0] => Array
                            (
                                [id] => 3
                                [name] => Messenger
                                [items] => 
                            )
                        [1] => Array
                            (
                                [id] => 4
                                [name] => Sling
                                [items] => 
                            )
                    )
            )
        [1] => Array
            (
                [id] => 2
                [name] => ACCESSORIES
                [items] => Array
                    (
                        [0] => Array
                            (
                                [id] => 5
                                [name] => Earrings
                                [items] => 
                            )
                        [1] => Array
                            (
                                [id] => 6
                                [name] => Clip
                                [items] => 
                            )
                    )
            )
    )