在 PHP 的层次结构中查找父键

Find parent keys in hierarchy in PHP

我有 $arrayArray 结构。

Array
  (
       [WIDGET_BUILDER_CREATE] => Array
       (
        [TITLE] => Widget Builder
        [WIDGET_TYPE_LBL] => Select Widget Type
        [RANGE_LBL] => Select Range
        [RANGE_TYPE_LBL] => Select Range Type
        [TOP_SERVICE_CHKBOX] => Top Services
        [SR_STATE_LBL] => Select Sr States
        [SR_TYPE_LBL] => Select Sr Types
        [SR_CATEGORY_LBL] => Select Sr Categories
        [SR_SOURCE_LBL] => Select Sources
        [SR_PROVIDER_LBL] => Select Sr Provider
        [ADDRESS] => Enter Address
        [SUBMIT_BTN] => Generate Data
        [CHART_DIV] => Array
            (
                [TYPE] => Select chart type
                [SAVE_BTN] => Save Widget
                [SERIES_NAME] => Change Parameters
                [PARA_DIALOG] => Array
                    (
                        [TITLE] => Chart Parameters
                        [SERIESNAME] => Series Name
                        [YAXISNAME] => Y axies name
                        [VALIDATION] => Array
                            (
                                [SERIESNAME] => Please enter series name
                                [YAXISNAME] => Please enter y axis name
                            )

                        [SAVE_BTN] => Save
                        [CANCEL_BTN] => Cancel
                    )

                [SAVE_DIALOG] => Array
                    (
                        [TITLE] => Save Chart
                        [CHART_NAME] => Chart Name
                        [SHOW_TO_USER] => System Widget
                        [VALIDATION] => Array
                            (
                                [CHART_NAME] => Please enter chart name
                            )

                        [SAVE_BTN] => Save
                        [CANCEL_BTN] => Cancel
                    )

            )

        [GRID_DIV] => Array
            (
            )

    )

  )

问题:

我想在 PHP 中构建一个函数,如果我输入一个值,那么它应该 return 层次结构中的所有父键。

例如,如果我输入 Please enter y axis name,它应该 return 为

$array['WIDGET_BUILDER_CREATE']['CHART_DIV']['PARA_DIALOG']['VALIDATION']['YAXISNAME'];

编辑: 我试过 How to get hierarchy path of an element in an Array 但它 return 是一个字符串,但我想作为索引的数组键。也就是说

print_r($array['WIDGET_BUILDER_CREATE']['CHART_DIV']['PARA_DIALOG']['VALIDATION']['YAXISNAME']);

//returns Please enter y axis name

我正在使用 PHP 5.5.9

下面的函数在 $source 数组和 returns 数组中搜索 $target 值的所有匹配路径。如果在 $source 中找不到该值,它 returns 一个空数组。

function pathFinder($target, array $source, $parentPath=''){
    $results=[];
    foreach($source as $k => $v){
        $path = $parentPath.'/'.$k; //current path
        //if element is array, recurse and import found results
        if(is_array($v) && $result=pathFinder($target, $v,$path)){
            foreach($result as $r) array_push($results,$r);
        }
        //else add element to results if it matches $target
        elseif($v===$target) $results[]=$path;     
    }
    return $results;
}

用法:

$target = 'Please enter axis Y name';
$foundPaths = pathFinder($target, $array);

Live demo

If you are feeling like you could use a quick & dirty approach, you may want to try the function below which uses nested foreach Loops. But then, if you are feeling geeky, you could simply refactor the nested loops on your own and turn them into a shorter recursive algorithm. To test this Quick & Dirty method, go here:

示例数据:

<?php

    $array = [
        'WIDGET_BUILDER_CREATE' => [
            "TITLE"                 => "Widget Builder",
            "WIDGET_TYPE_LBL"       => "Select Widget Type",
            "RANGE_LBL"             => "Select Range",
            "RANGE_TYPE_LBL"        => "Select Range Type",
            "TOP_SERVICE_CHKBOX"    => "Top Services",
            "SR_STATE_LBL"          => "Select Sr States",
            "SR_TYPE_LBL"           => "Select Sr Types",
            "SR_CATEGORY_LBL"       => "Select Sr Categories",
            "SR_SOURCE_LBL"         => "Select Sources",
            "SR_PROVIDER_LBL"       => "Select Sr Provider",
            "ADDRESS"               => "Enter Address",
            "SUBMIT_BTN"            => "Generate Data",
            "CHART_DIV"             => [
                "TYPE"          => "Select chart type",
                "SAVE_BTN"      => "Save Widget",
                "SERIES_NAME"   => "Change Parameters",
                "PARA_DIALOG"   => [
                    "TITLE"         => "Chart Parameters",
                    "SERIESNAME"    => "Series Name",
                    "YAXISNAME"     => "Y axies name",
                    "VALIDATION"    => [
                        "SERIESNAME"    => "Please enter series name",
                        "YAXISNAME"     => "Please enter y axis name",

                    ],
                    "SAVE_BTN"          => "Save",
                    "CANCEL_BTN"        => "Cancel",
                ],
                "SAVE_DIALOG"   =>[
                    "TITLE"         => "Save Chart",
                    "CHART_NAME"    => "Chart Name",
                    "SHOW_TO_USER"  => "System Widget",
                    "VALIDATION"    => [
                        "CHART_NAME"    => "Please enter chart name",
                    ],
                    "SAVE_BTN"      => "Save",
                    "CANCEL_BTN"    => "Cancel",
                ],

            ],
            "GRID_DIV"              => [],
        ],
    ];

快速和脏功能:

<?php

    function keywordLookUp(array $array, $keyWord, $arrayName="$array"){
        $route   = $mainKey   = null; $arrRte   = $arrResult   = [];
        foreach($array as $intKey=>$item){
            $mainKey =  $route = "{$arrayName}['{$intKey}']";
            if(is_array($item)){
                foreach($item as $iKey=>$innerItem){
                    if($lKey = array_search($keyWord, $item)){
                        $route .=  $s = "['$lKey']"; break;
                    }
                    if(is_array($innerItem)){
                        foreach($innerItem as $iKey2=>$innerItem2){
                            if($lKey = array_search($keyWord, $innerItem)){
                                if(isset($s)){
                                if(! array_search($route, $arrRte)){$arrRte[] = $route;}
                                    $arrRte[] =  "{$s}['$lKey']";
                                    $route .=  "\n{$s}['$lKey']";
                                }else{
                                    $route .=  "['$iKey']['$lKey']";
                                }   $s      =  str_replace("['$lKey']", "", $route); break;
                            }
                            if(is_array($innerItem2)){
                                foreach($innerItem2 as $iKey3=>$innerItem3){
                                    if($lKey = array_search($keyWord, $innerItem2)){
                                        if(isset($s)){
                                            if(! array_search($route, $arrRte)){$arrRte[] = $route;}
                                            $arrRte[] ="{$s}['$iKey2']['$lKey']";
                                            $route .=  "\n{$s}['$iKey2']['$lKey']";
                                        }else{
                                            $route .=  "['$iKey']['$iKey2']['$lKey']";
                                        }   $s      =  str_replace("['$iKey2']['$lKey']", "", $route); break;
                                    }
                                    if(is_array($innerItem3)){
                                        foreach($innerItem3 as $iKey4=>$innerItem4){
                                            if($lKey = array_search($keyWord, $innerItem3)){
                                                if(isset($s)){
                                                    if(! array_search($route, $arrRte)){$arrRte[] = $route;}
                                                    $arrRte[] = "{$s}['$iKey3']['$lKey']";
                                                    $route .=  "\n{$s}['$iKey3']['$lKey']";
                                                }else{
                                                    $route .=  "['$iKey']['$iKey2']['$iKey3']['$lKey']";
                                                }break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        $fin = ($route == $mainKey) ? null : $route;
        $fin = (!empty($arrRte) && sizeof($arrRte > 1))?$arrRte:$fin;
        return $fin;
    }

    $path  = keywordLookUp($array, "Please enter y axis name");
    $path2 = keywordLookUp($array, "Chart Parameters");
    $path3 = keywordLookUp($array, "Cancel");

    var_dump($path);
    // PRODUCES::  string '$array['WIDGET_BUILDER_CREATE']['CHART_DIV']['PARA_DIALOG']['VALIDATION']['SERIESNAME']' (length=87)

    var_dump($path2);
    // PRODUCES::  string '$array['WIDGET_BUILDER_CREATE']['CHART_DIV']['PARA_DIALOG']['TITLE']' (length=68)

    var_dump($path3);
    // PRODUCES:: 
    array (size=2)
      0 => string '$array['WIDGET_BUILDER_CREATE']['CHART_DIV']['PARA_DIALOG']['CANCEL_BTN']' (length=73)
      1 => string '$array['WIDGET_BUILDER_CREATE']['CHART_DIV']['SAVE_DIALOG']['CANCEL_BTN']' (length=73)