2016-05-25 6 views
0

このRecursive Functionを使用して、PHP配列を親と子の配列に変換したいと考えています。Cakephp3ビューセルで再帰関数を使用する

私は、このセルがあります。

class MenuCell extends Cell { 
    public function display($menu) { 
    $this->loadModel('Menus'); 
    $menus = $this -> Menus -> find('all', [ 
     'contain' => ['MenuItems'] 
    ]) -> where(['id' => $menu]); 

    $menus = $this -> buildTree($menus); 


    $this -> set(compact('menus')); 
    $this -> set('_serialize', ['menus']); 

    } 

    public function buildTree($ar, $pid = null) { 
    $op = array(); 
    foreach($ar as $item) { 
     if ($item['parentId'] == $pid) { 
     $op[$item['id']] = array(
      'name' => $item['name'], 
      'parentId' => $item['parentId'] 
     ); 
     // using recursion 
     $children = $this ->buildTree($ar, $item['id']); 
     if ($children) { 
      $op[$item['id']]['children'] = $children; 
     } 
     } 
    } 
    return $op; 
    } 


} 

をしかし、それは私にこのエラー与える:私は、コントローラでsamethingをすれば、それは非常にうまく動作しますが enter image description here

を。 私の一日を助ける助けがあれば。

+2

あなたが最初にこのような問題をデバッグする必要があり、このような質問をする前に!関連するメモで、なぜあなたは[** 'find( 'threaded')' **](http://book.cakephp.org/3.0/en/orm/retrieving-data-and-resultsets)を使わないでください。 html#finding-threaded-data)? – ndm

+0

私はモデルからスレッドを見つける必要はありません。私は配列内のすべてを見つけて、その配列に対して操作を実行したい。 申し訳ありませんが私はそれらのエラーを参照してください。私は次回に気をつけます –

+0

@ManjeetBarnalaこれは最高のひどい貧弱なハックであり、明らかに**解決策ではありません。 1000 - それは16分です。私はユーザーがずっと前に去ってしまったと確信しています。またはあなたのshittyコードがメモリ制限を吹き飛ばすか、別のエラーが発生します。 ***症状を修正してください、症状ではありません!*** – burzum

答えて

1

あなたはこれを試す動のメニューを作成したい場合:あなたのMenusTableをチェック

まず、あなたのテーブルには親ID(私の例では、PARENT_ID)でフィールドを持っており、関係belongsToのを作成する必要があり、hasManyの

メニューモデル

class MenusTable extends Table 
{ 

    public function initialize(array $config) 
    { 
     parent::initialize($config); 

     $this->table('menus'); 
     $this->displayField('name'); 
     $this->primaryKey('id'); 

     $this->addBehavior('Timestamp'); 
     $this->addBehavior('Tree'); 

     $this->belongsTo('ParentMenus', [ 
      'className' => 'Menus', 
      'foreignKey' => 'parent_id' 
     ]); 
     $this->hasMany('ChildMenus', [ 
      'className' => 'Menus', 
      'foreignKey' => 'parent_id' 
     ]); 
    } 

} 

MenuCell

class MenuCell extends Cell { 
    public function display($menu) { 
     $this->loadModel('Menus'); 

     $menus = $this->Menus->find('threaded')->where(['id'=>$menu])->toArray(); 

     $menus = $this->buildTree($menus); 

     $this->set(compact('menus')); 
     $this->set('_serialize', ['menus']); 
    } 

    //Recursive function: 

    protected function buildTree($menus) { 

     foreach($menus as $element) { 

      if(!is_array($element)) { 
       $element = $element->toArray(); 
      } 

      //Elements each menu array 
      $menu['name'] = $element['name']; 
      $menu['url'] = $element['url']; 

      foreach($element as $key => $value){ 

       if(is_array($value)) { 
        $menu[$key] = $this->buildTree($value); 
       } 

      } 
      $resultMenu[] = $menu; 
     } 

     if(isset($resultMenu)) { 
      return $resultMenu; 
     } 
    } 
} 

例結果:

[ 
    (int) 0 => [ 
     'name' => 'Level_1', 
     'url' => '/', 
     'children' => null 
    ], 
    (int) 1 => [ 
     'name' => 'Level_1', 
     'url' => '/', 
     'children' => [ 
      (int) 0 => [ 
       'name' => 'Level_1.1', 
       'url' => '/', 
       'children' => [ 
        (int) 0 => [ 
         'name' => 'Level_1.1.1', 
         'url' => '/', 
         'children' => null 
        ], 
        (int) 1 => [ 
         'name' => 'Level_1.1.1', 
         'url' => '/', 
         'children' => null 
        ] 
       ] 
      ], 
      (int) 1 => [ 
       'name' => 'Level_1.1', 
       'url' => '/', 
       'children' => null 
      ] 
     ] 
    ], 
    (int) 2 => [ 
     'name' => 'Level_1', 
     'url' => '/', 
     'children' => null 
    ], 
    (int) 3 => [ 
     'name' => 'Level_1', 
     'url' => '/', 
     'children' => null 
    ] 
] 
+0

はい私は以前同じことをしました。私はツリーの振る舞いを使って、それ自体すべてを処理しました。ありがとう。 –