3

MySQL DB クエリを使用して動的に複雑なメニュー構造を構築する必要があります。クエリを使用すると、ユーザーが使用および表示できるメニュー項目を定義できます。Menu 構造は、各要素が独自の ID を持ち、その親 ID に依存する従来の親子関係で結果セットに格納されます。Parent id = 0 は、その要素の上に親がないことを意味します (これはルートです)。

MNU_ID    MNU_FUNC    MNU_PARENT    MNU_ICON    MNU_TITLE_IT    MNU_TITLE_EN
----------------------------------------------------------------------------
  1       FLTMGR      0             home        STATO FLOTTA    FLEET STATUS
  2       PSTN        0             map-marker  POSIZIONI       POSITIONS
  3       RTS         0             road        PERCORSI        ROUTES
  4       CHRTS       0             line-charts DIAGRAMMI       CHARTS
  ...
  13      MNLS        0             book        MANUALI         MANUALS
  14      RGLTNS      0             bank        NORMATIVE       REGULATIONS
  16      SPD         4             tachometer  VELOCITA'       SPEED
  17      ALT         4             area-chart  ALTITUDINE      ALTITUDE
  18      DST         4             exchange    DISTANZA        DISTANCE
  ...
  32      INSTL       13            book        INSTALLAZIONE   SETUP
  33      BASE        32            wrench      BASE            BASE
  34      FLPR        32            wrench      SONDA CARB.     FUAL PROBE

ご覧のとおり、要素 33 と 34 は要素 32 の下にありますが、要素 32 は要素 13 の下にあり、最後に要素 13 はルート要素であるため親がありません (MNU_PARENT は 0 です)。さて、私は以下を返すようにコードを開発したと言いました:

Array(
[FLTMGR] => Array(
    [icon] => fa fa-home
    [title] => STATO FLOTTA
    ),
[PSTN] => Array(
    [icon] => fa fa-map-marker
    [title] => POSIZIONI
    ),
[RTS] => Array(
    [icon] => fa fa-road
    [title] => PERCORSI
    ),
[CHRTS] => Array(
    [icon] => fa fa-line-charts
    [title] => DIAGRAMMI
    [sub] => Array(
            [SPD] => Array(
                [icon] => fa fa-tachometer
                [title] => VELOCITÁ
                ),
            [ALT] => Array(
                [icon] => fa fa-area-chart
                [title] => ALTITUDINE
                ),
            [DST] => Array(
                [icon] => fa fa-exchange
                [title] => DISTANZA
                ),
            [GSLN] => Array(
                [icon] => fa fa-tint blink
                [title] => CARBURANTE
                )
            )
        ),
...
[MNLS] => Array(
    [icon] => fa fa-book
    [title] => MANUALI
    [sub] => Array(
        [INSTL] => Array(
            [MNU_ID] => 32
            [MNU_FUNC] => INSTL
            [MNU_PARENT] => 13
            [icon] => fa fa-book
            [title] => INSTALLAZIONE
            [sub] => Array(
                [0] => Array(
                    [MNU_ID] => 33
                    [MNU_FUNC] => BASE
                    [MNU_PARENT] => 32
                    [icon] => fa fa-wrench
                    [title] => BASE
                    ),
                [1] => Array(
                    [MNU_ID] => 34
                    [MNU_FUNC] => FLPR
                    [MNU_PARENT] => 32
                    [icon] => fa fa-wrench
                    [title] => SONDA CARB.
                    )
                )
            )
        )
    ),
[RGLTNS] => Array( 
    [icon] => fa fa-bank
    [title] => NORMATIVE
    )
)

ただし、ご覧のとおり、最初のレベルで正しい構造を生成できません。つまり、MNLS の下の INSTL 要素を見ると、次のエラーがあります。

  1. 項目 MNU_ID,MNU_FUNC,MNU_PARENT は存在しないはずです (その他を参照)
  2. 「サブ」の下のアイテムには、1 と同じエラーがあります。
  3. 「サブ」の下の項目は、0 と 1 ではなく、BASE、FLPR によって識別される必要があります

したがって、予想される構造は次のようになります。

Array(
[FLTMGR] => Array(
    [icon] => fa fa-home
    [title] => STATO FLOTTA
    ),
[PSTN] => Array(
    [icon] => fa fa-map-marker
    [title] => POSIZIONI
[RTS] => Array(
    [icon] => fa fa-road
    [title] => PERCORSI
    ),
[CHRTS] => Array(
    [icon] => fa fa-line-charts
    [title] => DIAGRAMMI
    [sub] => Array(
            [SPD] => Array(
                [icon] => fa fa-tachometer
                [title] => VELOCITÁ
                ),
            [ALT] => Array(
                [icon] => fa fa-area-chart
                [title] => ALTITUDINE
                ),
            [DST] => Array(
                [icon] => fa fa-exchange
                [title] => DISTANZA
                ),
            [GSLN] => Array(
                [icon] => fa fa-tint blink
                [title] => CARBURANTE
                )
            )
        ),
...
[MNLS] => Array(
    [icon] => fa fa-book
    [title] => MANUALI
    [sub] => Array(
        [INSTL] => Array(
            [icon] => fa fa-book
            [title] => INSTALLAZIONE
            [sub] => Array(
                [BASE] => Array(
                    [icon] => fa fa-wrench
                    [title] => BASE
                    ),
                [FLPR] => Array( 
                    [icon] => fa fa-wrench
                    [title] => SONDA CARB.
                    )
                )
            )
        )
    ),
[RGLTNS] => Array(
    [icon] => fa fa-bank
    [title] => NORMATIVE
    )
)

そして今、コード:

// $MenuDB contains the Menu structure returned by the DB

// Build the basic structure
$new = array();
foreach ($MenuDB as $a){
    $new[$a['MNU_PARENT']][] = $a;
    }

// Calls the recursive function CreateTree 
$tree = createTree($new, $new[0]);  

// Make final correction (remove unwanted items and replace index with keys)
$b=replaceKeys($tree);

print_r($b);
exit();

function replaceKeys(array $input) {    
    foreach($input as $key => &$val){                   // Scan the input array, each element will go in $val, the key will be $key
        $input[$val['MNU_FUNC']]=$input[$key];          // Replace index with key, the key is the value of the field MNU_FUNC
        if(is_numeric($key)) unset($input[$key]);       // Remove the item with numeric key (index) and leave the item with non-numeric index (key)
        unset($val['MNU_ID']);                          // Remove ID
        unset($val['MNU_PARENT']);                      // Remove Parent
        unset($val['MNU_FUNC']);                        // Remove Function
        if(isset($val['sub'])) {                        // avoid to work with undefined items
            if (is_array($val['sub'])) {                // check if there are childs inside the 'sub' item
                $val['sub'] = replaceKeys($val['sub']); // if we have childs, do it again recursively
                unset($val['url']);                     // remove url element if we have childs
                unset($val['url_target']);              // remove url_target element if we have childs
                }
            }
        }
    return $input;
    }

function createTree(&$list, $parent){
    $tree = array();
    foreach ($parent as $k=>$l){
        if(isset($list[$l['MNU_ID']])){
            $l['sub'] = createTree($list, $list[$l['MNU_ID']]);
            }
        $tree[] = $l;
        } 
    return $tree;
    }

私の努力にもかかわらず、エラーがどこにあるのかわかりません。私のワークフローに代わるものはありますか?

4

2 に答える 2

0

このコードは問題を解決しました:

$new = array();
foreach ($MenuDB as $a){
    $new[$a['MNU_PARENT']][] = $a;
    }

$tree = createTree($new, $new[0]);  

print_r($tree).PHP_EOL;

exit();


function createTree(&$list, $parent){
    $tree = array();
    foreach ($parent as $k=>$l){
        if(isset($list[$l['MNU_ID']])){                       // check if current element has childs 
            $l['sub'] = createTree($list, $list[$l['MNU_ID']]); // build child structure inside 'sub'
            unset($l['url']);                                    // remove the 'url' item for elements having childs
            unset($l['url_target']);                             // remove the 'url_target' item for elements having childs
            }
        unset($l['MNU_ID']);                                    // remove the 'MNU_ID' item not needed anymore
        unset($l['MNU_PARENT']);                                // remove the 'MNU_PARENT' item not needed anymore
        //$tree[] = $l;
        $tree[$l['MNU_FUNC']]=$l;                               // while $tree[] = $l; will transfer the elements array to $tree using index, this one will will transfer the elements array to $tree using the key $l['MNU_FUNC'] 
        unset($tree[$l['MNU_FUNC']]['MNU_FUNC']);               // remove the 'MNU_FUNC' item not needed anymore 
        } 
    return $tree;
    }

これは短く、さらに太っています! 2 つのパッセージreplaceKeysは絶対に必要ないので、内部ですべてのことを行うことができますcreateTree

于 2018-01-16T11:09:45.127 に答える