Ссылка на элементы многомерного массива на основе строки без eval
Хорошо, я работаю с большим многомерным массивом, в котором содержится больше информации, чем мне нужно, и я хочу пройтись по нему, чтобы отфильтровать интересующие меня данные. К сожалению, этот многомерный массив создается динамически и не всегда содержит данные, которые я хочу, поэтому я должен использовать логику, как:
if(isset($ar['b']['ba']['baa'])){
echo '<h3>'.$ar['b']['ba']['baa'].'</h3>';
}
if(isset($ar['b']['ba']['baba'])){
echo '<h3>'.$ar['b']['ba']['baba'].'</h3>';
}
if(isset($ar['b']['ba']['babb'])){
echo '<h3>'.$ar['b']['ba']['babb'].'</h3>';
}
Вышеописанное прекрасно работает, но выглядит немного грязно, поэтому я преобразовал вышеприведенное в:
$refAr=array();
$refAr[]='b->ba->baa';//3
$refAr[]='b->ba->bab->baba';//4
$refAr[]='b->ba->bab->babb';//5
Вышеприведенное выглядит намного более красиво и аккуратно, и именно так я хочу управлять сценарием на случай, если в будущем мне понадобятся ссылки на разные ключи. Проблема, с которой я столкнулся, заключается в попытке использовать вышеуказанный формат для ссылки на массив. Я думал, что переменные переменные будут работать, но, очевидно, это не сработает. Моя вторая попытка использования eval сработала, но я не очень доволен своим решением. Вот где вы, ребята, должны прийти, есть ли лучший способ сделать это? Вот моя попытка ниже:
<?php
$ar=array(
'a'=>array('aa'=>1,'ab'=>2),
'b'=>array(
'ba'=>array('baa'=>3,'bab'=>array('baba'=>4,'babb'=>5),'bac'=>array('baca'=>6,'bacb'=>7)),
)
);
$refAr=array();
$refAr[]='b->ba->baa';//3
$refAr[]='b->ba->bab->baba';//4
$refAr[]='b->ba->bab->babb';//5
foreach($refAr as $ref)
{
$r=explode('->',$ref);
$r="\$ar['".implode("']['",$r)."']";
echo '<h1>'.$r.'</h1>';
echo '<h3>'.$$r.'</h3>';//undefined
eval('$t='.$r.';');
echo "<h3>$t</h3>";//works but uses eval, is there a better way?
}
2 ответа
Я решил ответить на свой вопрос. Вот что я использовал:
<?php
//Sample PHP representation of dynamically-pulled JSON data from an untrusted source
$ar=array(
'a'=>array('aa'=>1,'ab'=>2),
'b'=>array(
'ba'=>array('baa'=>3,'bab'=>array('baba'=>4,'babb'=>5),'bac'=>array('baca'=>6,'bacb'=>7)),
)
);
//Reusable function
function resolveReference($ar,&$ref)
{
$t = $ar;
foreach ( explode('->',$ref) as $v )
{
if (!array_key_exists($v,$t)){$ref=null;return false;}
$t = $t[$v];
}
$ref=$t;
return true;
}
//The references I'm interested in but don't know if my dynamic data will contain these keys every time
$refAr=array();
$refAr[]='b->ba->baa';
$refAr[]='b->ba->bab->baba';
$refAr[]='b->ba->bab->babb';
$refAr[]='b->doesnt->exist';
foreach($refAr as $ref)
{
echo '<h1>'.$ref.'</h1>';
if(resolveReference($ar,$ref))
{
echo '<h3><span style="color:blue;">'.$ref.'</span></h3>';
}else{
echo '<h3><span style="color:red;">Alternative text for non-existent expected reference</span></h3>';
}
}
Ты можешь попробовать
$ar = array();
$ar['b']['ba']['baa'] = 3;
$ar['b']['ba']['bab']['baba'] = 4;
$ar['b']['ba']['bab']['babb'] = 5;
$refAr = array();
$refAr[] = 'b->ba->baa'; // 3
$refAr[] = 'b->ba->bab->baba'; // 4
$refAr[] = 'b->ba->bab->babb'; // 5
foreach ( $refAr as $ref ) {
$t = $ar;
foreach ( explode("->", $ref) as $v ) {
if (!isset($t[$v]))
break;
$t = $t[$v];
}
is_array($t) and $t = null;
echo "<h3>$t</h3>";
}
Выход