Может ли обратный вызов PHP принять свой параметр ( s) по ссылке?

Я протестировал следующее, и оно работает как на PHP 5.2, так и на 5.3, однако, насколько я могу судить, нигде не документировано, поэтому я оцениваю его использование.

У меня есть функция в классе isValid, она проверяет хеш, чтобы увидеть, находится ли данное значение в наборе допустимых значений. Есть некоторые значения, которые являются действительными, но не рекомендуются; Я бы хотел, чтобы моя функция isValid обновляла переданное значение до текущего и возвращала значение true.

Это хорошо, когда я сам вызываю его, однако я хотел бы использовать этот метод, когда он используется в качестве обратного вызова для array_filter. тоже.

Вот тестовый пример, который, как и ожидалось, приводит к массиву со значениями 2,3,4,5,6.

<?php
$test = array(1, 2, 3, 4, 5);
echo print_r(array_filter($test, 'maptest'), true);

function maptest(&$value)
{
$value ++;
return true;
}

Итак, StackOverflow: это разрешено, или это недокументированная функциональность, которая может исчезнуть / перестать работать / вызвать ошибки в будущем?

7
задан philjohn 20 August 2010 в 14:01
поделиться

2 ответа

Да, можно.

В этом отношении нет ничего особенного в вызове функций через обратные вызовы.

Однако ваш конкретный пример не иллюстрирует одну трудность. Учтите:

function inc(&$i) { $i++; }
$n = 0;
// Warning:  Parameter 1 to inc() expected to be a reference, value given:
call_user_func('inc', $n);

Проблема в том, что вы передаете $ n в call_user_func , а call_user_func не принимает значения по ссылке. Таким образом, к моменту вызова inc он не получит ссылку. Это не проблема с array_filter , потому что он проходит через массив напрямую и может напрямую передавать переменные в массиве в функцию обратного вызова.

Вы можете использовать передачу по ссылке во время вызова, но это устарело и удалено из магистрали:

function inc(&$i) { $i++; }
$n = 0;
// Deprecated: Call-time pass-by-reference has been deprecated
call_user_func('inc', &$n);

Так что лучший вариант - использовать вместо него call_user_func_array :

function inc(&$i) { $i++; }
$n = 0;
call_user_func_array('inc', array(&$n));

Эта функция будет передавать по ссылке элементы, для которых установлен флаг is_ref , и передавать по значению другие.

9
ответ дан 7 December 2019 в 01:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: