Подтвердить что ты не робот

Как определить, установлена ​​ли переменная pass-by-reference?

Для произвольной функции, объявленной следующим образом:

function foo($first, &$second = null) {
    // if ($second is assigned) {
    //     Work with $second
    // }
}

Как определить, действительно ли $second присваивается переменной во время вызова, например.:

foo('hello', $second);

против

foo('hello'); // Notice &$second is unassigned

Пробовал isset(), is_null(), но они, похоже, не работают.

Обновление:

Создал test script здесь здесь

4b9b3361

Ответ 1

Я понимаю, что вы хотите реализовать функцию, которая реализует нечто вроде preg_match, посредством чего третий аргумент заполняется патчами памяти, если они переданы.

Внутренне функции PHP используют функцию под названием zend_parse_parameters(); он принимает строку формата и переменное количество аргументов, которые будут заполнены метаданными параметров вызова. Если параметр не передан (например, когда он является необязательным), метаданные недоступны и поэтому легко обнаружить.

Возвращаясь к самому PHP, к сожалению, нет такой вещи, как func_arg_used($var), которая сообщит вам, был ли $var передан как аргумент функции; возможно, это будет интересным вкладом в язык, но до тех пор вам придется довольствоваться чем-то более древним:)

if (func_num_args() > 1) {
    // $second was passed and can be used to populate
}

Возможно, вам придется проявлять осторожность при изменении сигнатуры функции, особенно когда вы добавляете параметры перед $second; однако, естественно, это не должно происходить часто, потому что это наиболее определенно нарушит зависимые функции. Добавление дополнительных аргументов в конец не влияет на код выше.

Есть два способа сделать это:

  • ReflectionFunction - блестящая новая игрушка разработчиков, она позволяет вам исследовать вашу функцию и определять, изменилась ли подпись с когда он был создан. Используйте его экономно, хотя, самоанализ не дешев, особенно учитывая альтернативу.

  • Смиренный комментарий к коду - очень заниженная форма управления кодом; простая строка, в которой говорится // IMPORTANT - don't add arguments before $second

Ответ 2

Вы не можете (насколько я знаю) рассказать разницу между NULL и Undefined с помощью isset. Вы можете установить значение по умолчанию $second для некоторого случайного значения, которое никогда не будет использоваться иначе.

define('UNDEFINED', -19181818);

function foo($first, &$second = UNDEFINED) 
{
 if($second==UNDEFINED)
 {
  etc..
 }
}

Ответ 3

Работает для меня:

<?php

function bool_str($b)
{
    return ($b ? "true" : "false");
}

function foo($first, &$second = null)
{
    echo bool_str(isset($first)) . " " . bool_str(isset($second)) . " " .
         bool_str(is_null($first)) . " " . bool_str(is_null($second)) . "\n";
}

$a = 1;
$b = 2;

foo($a, $b);
foo($a);

?>

Вывод:

true true false false
true false false true
     ^^^^^       ^^^^

Это именно то, чего я ожидал бы, т.е. здесь можно использовать как isset, так и is_null.

Ответ 4

Я думаю, что предложение Джека использовать func_num_args() отлично.

function foo($first, &$second = null) {
    if (func_num_args() > 1) {
        //$second MUST be assigned
    }
}

Это правильно определяет, когда $second ссылается на переменную, которая существует в таблице символов вызывающих областей, но имеет значение переменной null.

$second = null;
foo('hello', $second);