2016-03-28 7 views
2

私は以下のようなテーブル構造を持っています。item_id - > 1,2はメインメニュー項目です。item_id - > 3,4はparent_idで判断できるサブ項目ですphp yalinqo-iterate through result

enter image description here

私はこの結果をフェッチして繰り返します。 UI上でメニューを正しく構成することができます。

foreachループ 'foreach-1'を使用するまで、すべて正常に動作します。その結果は

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

しかし、私は、foreachループを追加するときに 'foreachの-2'。その結果、私はyalinqoライブラリを使用しています、

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

そして、あなたが見ることができるように以下のように(2-アクセサリー)を示していません結果セットからデータをフェッチします。そして、wwwのyalinqoに関する助けは非常に少ないです。

問題を作成している隠しカーソルがありますか? 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は:私は、メニューバーの構築のために存在する場合の周りの別のより効率的な作業を使用させていただきます。

+0

あなたはNoSQLのデータベースを使用することができますたとえば、mongoDBとデータベースのツリーを保存します。フィールドの親に配列を挿入するには、postgrySqlを使用します。または、グラフデータベースを使用します。あるいは、mysqlは素晴らしい5.7で、フォーマットjsonを使用します。より多くのことなどがありますが、1つのクエリですべてのデータと1つのインターレーターforeachを選択できます。 – Naumov

答えて

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レベルしかサポートされていません。 2つのレベルだけが必要な場合は、1つのクエリで簡単に実行できます。

のは、我々はすでに配列を持っていると仮定しましょう:

$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] => 
         ) 
       ) 
     ) 
)