The way you're doing does not look good. Always think that when you fall into complicated situations where you will have to deal with gross gambiarras, it is because there is something wrong in the logic. So, review the logic.
But if you want to continue, just try to understand the operation of these examples:
/*
Não sei qual a estrutura que retorna de $allItems = $model::all();
então fiz uma estrutura simples com array. Eu sei que retorna como stdclass (objeto), mas aqui quero mostrar um exemplo com array. Mais para frente você entenderá o motivo:
*/
$item = array(
'foo' => array(
'bar' => 'ok'
)
);
/*
Esse aqui seria o trecho 'obj_param' => 'district->name'
*/
$param = 'foo->bar';
/*
A lógica para montagem começa aqui. Vamos explodir num array.
*/
if (strpos($param, '->')) {
$arr = explode('->', $param);
/*
Então aplicamos a função array_reduce() para chegar ao valor de $item['foo']['bar'] a partir de uma string "foo->bar"
*/
$rs = array_reduce(
explode('->', $param),
function ($x, $key) {
if (isset($x[$key])) {
return $x[$key];
} else {
return null;
}
},
$item
);
/*
Resulta em
string(2) "ok"
*/
var_dump($rs);
}
Example with stdclass object
The logic is the same as the previous example with array, so I did not include comments:
$item = (object)array(
'foo' => (object)array(
'bar' => 'ok'
)
);
$param = 'foo->bar';
if (strpos($param, '->')) {
$arr = explode('->', $param);
/*
Isso aqui faz um "array_reduce" de um objeto.
*/
$rs = function($item) use (&$rs, &$arr) {
foreach ($arr as $k => $v) {
if (
isset($item->$v)
&& is_object($item->$v)
) {
unset($arr[$k]);
$item = $rs($item->{$v});
} else {
unset($arr[$k]);
return $item;
}
}
return current($item);
};
/*
Mostra o resultado
*/
var_dump($rs($item));
}
Both examples were created considering that you could use N produndity.
Example:
$param = 'foo->bar->bar2->bar3->bar4';
$param = 'foo->bar->bar2';
$param = 'foo->bar->bar->bar';
$param = 'foo->bar';
Simple example, with static depth
Another way to solve it without complicating it so much, but still doing it is if you are sure of the depth limit of the object's keys.
If you only have 2, it is quite easy because a simple explode () already solves half of the problem:
$item = (object)array(
'foo' => (object)array(
'bar' => 'ok'
)
);
$param = 'foo->bar';
if (strpos($param, '->')) {
$arr = explode('->', $param);
var_dump($item->$arr[0]->$arr[1]);
}
Of course you need to use isset($item->$arr[0])
before you want to invoke $item->$arr[0]->alguma_coisa
. In this example I refrain from creating consistency checks to simplify teaching.
Summary
You have 3 paths
Use eval ()
OMG no!
Reducing an array / object iteratively according to the examples above
It is more than a gambiarra, it is a complication.
Rewrite a new logic
Recommended!