Php 基于另一个键的条件的数组递归替换?

Php 基于另一个键的条件的数组递归替换?,php,multidimensional-array,Php,Multidimensional Array,我有一个动态多维数组,深度未知。我想根据另一个key=>value条件替换一个key=>value值 例如,当$form\u id为1f44537时,替换$settings[$cient\u id]的值 $data=array( 0 => 排列( 'id'=>'2cd5985', “elType”=>“节”, “设置”=>array(), “元素”=>数组( 0=>数组( 'id'=>'88063e6', 'elType'=>'column', “设置”=>array(), “元素”=>数组(

我有一个动态多维数组,深度未知。我想根据另一个
key=>value
条件替换一个
key=>value

例如,当
$form\u id
1f44537
时,替换
$settings[$cient\u id]
的值

$data=array(
0 => 
排列(
'id'=>'2cd5985',
“elType”=>“节”,
“设置”=>array(),
“元素”=>数组(
0=>数组(
'id'=>'88063e6',
'elType'=>'column',
“设置”=>array(),
“元素”=>数组(
0 => 
排列(
'id'=>'1f44537',
'elType'=>'widget',
“设置”=>数组(
“ap_google_sheet_client_id”=>“test_id”,
),
“元素”=>数组(
),
'widgetType'=>'form',
),
)
),
1=>数组(
'id'=>'7878c73',
'elType'=>'column',
“设置”=>array(),
“元素”=>数组(
0 => 
排列(
'id'=>'1f44537',
'elType'=>'widget',
“设置”=>数组(
“ap_google_sheet_client_id”=>“test_id”,
),
“元素”=>数组(
),
'widgetType'=>'form',
),
)
),
),
),
);
以下是我失败的尝试

Try-1

public function replace\u recursive($elements,$form\u id){
foreach($elements as&$element){
if($element['id']==$form\u id){
$element['settings']['ap\u google\u sheet\u client\u id']='replaced';
返回$elements;
}
如果(!empty($element['elements'])){
$elements=self::replace_recursive($element['elements'],$form_id);
如果($要素){
返回$elements;
}
}
}
}
Try-2

这就解决了问题。但是当找到元素时,循环不会停止。它在所有元素中循环

public function replace\u recursive($elements,$form\u id){
foreach($elements as&$element){
if($element['id']==$form\u id){
$element['settings']['ap\u google\u sheet\u client\u id']='replaced';
写日志('A');
打破
}
如果(!empty($element['elements'])){
self::replace_recursive($element['elements',$form_id);
写日志('B');
}
}
返回$elements;
}
值被替换,但我没有得到完整的数组$元素。而不是获取替换该值的子数组

Try-3

再次面对同样的问题。
elType=widget
顶部的命名键将转换为编号键。这是一个沙箱


如您所述,代码正在正确替换值。只是您当前返回的是递归调用返回的值
$elements
。但这是一个比整个数组更小的数组,因此不应该将该数组进一步向上冒泡

相反,只需在“elements”键处将该结果注入当前包装数组,并返回结果数组:

$data = [[
    'id' => '2cd5985',
    'elements' => [[
        'id' => '88063e6',
        'elements' => [[
            'id' => '1f44537',
            'settings' => [
                'form_name' => 'New Form',
                'form_fields' => [[
                    'custom_id' => 'name',
                    'field_label' => 'Name',
                    'placeholder' => 'Name',
                    '_id' => '948d900',
                    'field_pattern_message' => 'Please match the requested format',
                ],
                [
                    'custom_id' => 'email',
                    'field_type' => 'email',
                    'required' => 'true',
                    'field_label' => 'Email',
                    'placeholder' => 'Email',
                    '_id' => '243a095',
                    'field_pattern_message' => 'Please match the requested format',
                ]],
                'ap_google_sheet_client_id' => '',
            ],
            'elements' => [],
            'widgetType' => 'form',
        ]],
        'isInner' => false,
    ]],
    'isInner' => false,
]];

function replace_recursive( $elements, $form_id ) {
    foreach ( $elements as &$element) {
        if ( $element['id'] === $form_id ) {
            $element['settings']['ap_google_sheet_client_id'] = 'replaced';
            return $elements;
        }

        if ( ! empty( $element['elements'] ) ) {
            $subelements = replace_recursive( $element['elements'], $form_id );
            if ( $subelements ) { 
                // Inject result back into our array
                $element["elements"] = $subelements; 
                return $elements;
            }
        }
    }
}
    
$res = replace_recursive( $data, "1f44537");
var_dump($res);
请参阅另一个输入示例


在第二次尝试中,将
返回
放在循环外部。但这意味着您总是返回数组。然而,您需要某种指示,以确定是否发生了替换。如果没有替换值,最好返回
null
,而只有在有替换时才返回完整数组。否则,您没有指示何时可以停止进一步查看。

共享阵列的
var\u导出
,而不是print\u r()。@nice\u dev export在我的情况下不起作用。首先,它是一个大数组,其次,它给出了一个解析器错误,因为我使用了一些外部API。“它是一个大数组”不是问题,我们不要求您提供完整的源代码和完整的状态,但提供足够的细节来构成,这包括显示足够多的阵列,让人们真正了解您正在使用的阵列。如果这意味着只显示第一个元素:那很好。需要记住的一点是,理想情况下,您希望显示其他人可以运行的代码-对于您描述的问题,“API”是不可逆的:
replace\u recursive
接受两个参数,显示代表性代码,让人们在代表性数据上运行该函数。@Mike'Pomax'Kamermans我更新了问题。我使用的API在内部使用ajax,不打印任何内容。因此,最初无法进行var_转储或导出。但是现在我知道我也可以使用xdebug作为var_导出进行复制。谢谢。我现在正在做。但你的问题太复杂了。该示例数据中有很多与您的问题无关的数据。如果您只将数据缩减到关键部分,您将获得更大的成功。记住我们是志愿者。谢谢你的努力。你这边行吗?我试过了,但没有成功。你能复制粘贴你的全部代码吗?太棒了。这很有效。我在每个
return
语句之前分别插入
echoa
echob
。它应该先打印A,然后再打印B。但是为什么它要打印一个额外的B,即A B双映像呢?您还没有找到密钥,您需要进行递归调用。在该递归执行中,也找不到键,然后再次递归。每次调用堆栈增长时。所有这些递归调用都处于挂起状态(就在
if
之前)。因此,当最终获得匹配时,所有那些挂起的递归调用都将得到一个返回值(从最深处到顶部)。在每个级别,执行将继续执行
if
。当然,