Как я могу использовать ссылочную переменную в PHP функции лямбда

public function getAllByField(array &$condition)
{
return $this->repository->scopeQuery(
function ($query) use (&$condition) {
return $query->where('status', '!=', '9')->whereRaw(
array_reduce(
array_keys($condition), function ($carry, $k) use (&$condition) {
if(in_array('json', $item = $condition[$k])) {
$jsonColumns = explode('->', $item[0]);
unset($condition[$k]);

return  'JSON_VALUE('.$jsonColumns[0].',\'$.'.$jsonColumns[1].'\') '
.$item[1].' '
.(is_string($item[2])? '\''.$item[2].'\'':$item[2]);
}
}
)
);
}
)->findWhere($condition)->all();
}

я определяю вышеупомянутый метод в этом методе $condition переменная устанавливается по ссылке и в запросе сбрасывает некоторые значения, но когда я использую $condition в последней строке это изменение (unset()не сохранить!
как я могу сохранить изменилось $condition?

1

Решение

Ваша ошибка в том, что в вашей подписи вы используете array $condition вместо array &$condition и, следовательно, все ваши ссылки в lambas являются ссылками на первоначальную копию. Вот небольшой пример:

function removeTest(array &$condition)
{
(function () use (&$condition) {
if (isset($condition["test"])) {
unset($condition["test"]);
}
})();
}

$arr = ["test" => "test", "test2" => "test2"];
removeTest($arr);
print_r($arr); // prints ["test2" => "test2"]

Если вы удалите начальный & в сигнатуре removeTest не имеет значения, что лямбда-выражения используют переменные по ссылке, так как при первом вызове будет сделана копия, а оригинал $arr остался нетронутым.

Если бы вы использовали объекты вместо этого, это всегда по ссылке:

function removeTest($condition)
{
(function () use ($condition) {
if (isset($condition->test)) {
unset($condition->test);
}
})();
}

$obj = (object) ["test" => "test", "test2" => "test2"];
removeTest($obj);
print_r($obj); // prints stdClass Object("test2" => "test2")
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector