Может ли обратный вызов PHP принять свои параметры по ссылке? - PullRequest
7 голосов
/ 20 августа 2010

Я протестировал следующее и оно работает как на 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: эторазрешено или это недокументированная функциональность, которая может исчезнуть / перестать работать / вызвать ошибки в будущем?

Ответы [ 2 ]

9 голосов
/ 20 августа 2010

Да, это разрешено.

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

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

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 и будут передавать по значению другие.

1 голос
...