Меня смущают значения по умолчанию для функций PHP. Скажем, у меня есть такая функция:
function foo($blah, $x = "some value", $y = "some other value") {
// code here!
}
Что, если я хочу использовать аргумент по умолчанию для $ x и установить другой аргумент для $ y?
Я экспериментировал с разными способами, и я просто запутался. Например, я попробовал эти два:
foo("blah", null, "test");
foo("blah", "", "test");
Но оба из них не приводят к правильному аргументу по умолчанию для $ x. Я также попытался установить его по имени переменной.
foo("blah", $x, $y = "test");
Я полностью ожидал, что что-то подобное сработает. Но это не работает, как я ожидал. Кажется, что независимо от того, что я делаю, мне все равно придется заканчивать вводом аргументов по умолчанию, каждый раз, когда я вызываю функцию. И я, должно быть, упускаю что-то очевидное.
foo("blah", , "test");
?Ответы:
Я бы предложил изменить объявление функции следующим образом, чтобы вы могли делать то, что вы хотите:
Таким образом, вы можете сделать вызов как
foo('blah', null, 'non-default y value');
и заставить его работать, как вы хотите, где второй параметр$x
прежнему получает значение по умолчанию.При использовании этого метода передача нулевого значения означает, что вы хотите использовать значение по умолчанию для одного параметра, когда вы хотите переопределить значение по умолчанию для параметра, который следует за ним.
Как указано в других ответах,
Если у меня есть метод, который может принимать различное количество параметров и параметров разных типов, я часто объявляю функцию, подобную ответу, показанному Райаном П.
Вот еще один пример (это не отвечает на ваш вопрос, но, надеюсь, информативно:
источник
null
значения параметру, поскольку каждый раз он назначает значение по умолчанию. Даже в том случае, если у вас есть другое специальное значение для того, когда вы на самом деле хотите нулевое значение (например, когда $ x == "use_null" составляет $ x = null), вы не сможете назначить такое специальное значение в качестве литерального значения параметр (в данном случае строка «use_null»). Поэтому просто обязательно используйте уникальный, никогда не желаемый «ключ», когда вы хотите использовать значение по умолчанию (и вы хотитеnull
быть допустимым параметром)Необязательные аргументы работают только в конце вызова функции. Невозможно указать значение $ y в вашей функции без указания $ x. Некоторые языки поддерживают это с помощью именованных параметров (например, VB / C #), но не PHP.
Вы можете эмулировать это, если вы используете ассоциативный массив для параметров вместо аргументов - т.е.
Затем вызовите функцию так:
источник
isset($args['x'])
, так как оно в настоящее время заменяет пустую строку, пустой массив илиfalse
значение по умолчанию.$x = !array_key_exists('x',$args) ? 'default x value' : $args['x'];
На самом деле это возможно:
Хотели бы вы сделать это - другая история :)
ОБНОВИТЬ:
Причины, чтобы избежать этого решения:
Но это может быть полезно в ситуациях, когда:
Вы не хотите / не можете изменить исходную функцию.
Вы можете изменить функцию, но:
null
(или эквивалент) не вариант (см. комментарий DiegoDD )func_num_args()
Что касается производительности, очень простой тест показывает, что использование Reflection API для получения параметров по умолчанию делает вызов функции в 25 раз медленнее , хотя это по-прежнему занимает менее одной микросекунды . Вы должны знать, если вы можете жить с этим.
Конечно, если вы хотите использовать его в цикле, вы должны получить значение по умолчанию заранее.
источник
источник
$defaults = [ 'x' => 'some value', 'y' => 'some other value'];
Единственный способ, которым я знаю, - это пропустить параметр. Единственный способ пропустить параметр - это переставить список параметров так, чтобы тот, который вы хотите опустить, находится после параметров, которые вы ДОЛЖНЫ установить. Например:
Тогда вы можете позвонить Foo, как:
Это приведет к:
источник
Я недавно имел эту проблему и нашел этот вопрос и ответы. Хотя вышеуказанные вопросы работают, проблема в том, что они не показывают значения по умолчанию для IDE, которые его поддерживают (например, PHPStorm).
если вы используете,
null
вы не будете знать, какое значение будет, если вы оставите это поле пустым.Решение, которое я предпочитаю, состоит в том, чтобы поместить значение по умолчанию в определение функции также:
Разница лишь в том, что мне нужно убедиться, что они одинаковы, но я думаю, что это небольшая цена за дополнительную ясность.
источник
Вы не можете сделать это напрямую, но небольшая путаница кода позволяет эмулировать.
источник
null
в этом случае концептуально более аккуратным, чемfalse
.false
является более рискованным выбором, чемnull
php - язык не строгий.!$x
будет верно для нескольких разных входов, которые могут удивить программиста:0
,''
. Принимая во вниманиеnull
, что, вы можете использовать!isset
в качестве более строгого теста.источник
Мои 2 цента с нулевым оператором объединения
??
(начиная с PHP 7)Вы можете проверить больше примеров на моем repl.it
источник
Это тот случай, когда объект лучше - потому что вы можете настроить свой объект для удержания x и y, установить значения по умолчанию и т. Д.
Подход с массивом близок к созданию объекта (на самом деле, объект - это набор параметров и функций, которые будут работать над объектом, а функция, принимающая массив, будет работать над некоторыми параметрами).
Конечно, вы всегда можете сделать несколько трюков, чтобы установить ноль или что-то вроде этого по умолчанию
источник
Вы также можете проверить, есть ли у вас пустая строка в качестве аргумента, чтобы вы могли вызвать как:
foo('blah', "", 'non-default y value', null);
Ниже функции:
Неважно, если вы заполните
null
или""
, вы все равно получите тот же результат.источник
Передайте массив функции вместо отдельных параметров и используйте оператор объединения нулей (PHP 7+).
Ниже я передаю массив с 2 элементами. Внутри функции я проверяю, установлено ли значение для item1, если не назначено хранилище по умолчанию.
источник
$args['item1'] = $args['item1']??'default value';
в PHP 7+. если $ args ['item1'] равен нулю, тоdefault value
строка будет присваиваться $ args ['item1']