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


Find parent keys in hierarchy in PHP

对于$array,我有下面的Array结构。

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构建一个函数,就像如果我输入一个值,那么它应该返回层次结构中的所有父键一样。

举个例子,如果我输入Please enter y axis name,它应该返回为

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

编辑:我尝试过如何获取数组中元素的层次结构路径,但它以字符串形式返回,但我希望作为数组键进行索引。这意味着

print_r($array['WIDGET_BUILDER_CREATE']['CHART_DIV']['PARA_DIALOG']['VALIDATION']['YAXISNAME']);
//returns Please enter y axis name

我使用的是PHP 5.5.9

下面的函数搜索$source数组,并返回一个具有$target值的所有匹配路径的数组。如果在$source中找不到该值,则返回一个空数组。

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);

实时演示

如果你觉得你可以使用快速&dirty方法,您可能需要尝试下面的function,它使用嵌套的foreach循环。但是,如果你觉得自己很古怪,你可以简单地自己重构嵌套的循环,并将它们变成一个更短的递归算法。要测试此快速&脏方法,转到这里:

样本数据:

<?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)