それは怪物ですが、あなたが望むことをします。2回目の関数呼び出し後に参照が破棄されるため、再帰関数でpushを使用すると失敗します。したがって、キーの深さがわからない場合は、任意の数のループを使用するか、最適なものを期待して変数をインポートし、を使用するかを選択できます。 evalを使用して新しい値をプッシュするか、配列を分解して再構築します。私は評価を選びました。必要なものの説明は、配列ではなく配列内のキーと値のペアを探しているため、値をプッシュすることとは少し異なります。この関数は、キーと値のペアを検索し、必要なものを兄弟として追加します。値が指定されていない場合、値は最初に一致したキーに兄弟として追加されます。pushvalが指定されていない場合、一致したキー/キー値を指すキーのチェーンが返されます。
$ref_array
は変更するマルチ配列、
$key
は探しているキー、は
$val
探しているキーの
$newkey
値、は新しい値を参照する新しいキー、
$pushval
はでインデックス付けされる新しい値$newkey
です。
パラメータの引数を渡さない$val_array
でください。これは、リカッシブコールでのみ使用されます。これは、関数が新しい呼び出しと再帰呼び出しを区別する方法であり、関数が参照渡しを中断することなくキー値を見つける方法です。
function deepPush(&$ref_array, $key, $val=null, $newkey=null, $pushval=null, $val_array=null)
{
static $r, $keys;
#reset static vars on first call
if(!$val_array){ $r = 0; $keys = array();}
#cap recursion
if($r > 100){ trigger_error('Stack exceeded 100'); return;}
#init val_array
$val_array = ($r) ? $val_array : $ref_array;
#specified search value???
$search_val = ($val!==null && !in_array($val, $val_array)) ? true : false;
if(!array_key_exists($key, $val_array) || $search_val) {
$i=0;foreach($val_array as $k=>$v){
if(gettype($v) == 'array') {
if($i>0){/*dead-end*/array_pop($keys); /*keep recusion accurate*/$r-=$i;}
$keys[] = $k;/*build keychain*/
$r++; $i++; /*increment recursion, iteration*/
if(deepPush($ref_array, $key, $val, $newkey, $pushval, $v)){ /*close stack on 1st success*/return $keys;}
}//if
}//foreach
}//if
else{
if($pushval === null){return $keys;}
#add $newkey to the keychain
$keys[] = $newkey;
#process $pushval based on type
$pushval = (gettype($pushval) == 'string') ? sprintf("'%s'", $pushval) : var_export($pushval, true);
#link keys together to form pointer
$p = '$ref_array';
for($j=0,$c=count($keys); $j<$c; $j++) {
$k = $keys[$j];
$p .= "['$k']";
}//for
#concat the value to be pushed
$p .= sprintf("= %s;",$pushval);
#push it
eval($p);
$keys = array();
return true;
}//else
}
deepPush($array, 'id', 4, 'children', $addThis);