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

Любой способ указать дополнительные значения параметра в PHP?

Скажем, у меня есть функция PHP foo:

function foo($firstName = 'john', $lastName = 'doe') {
    echo $firstName . " " . $lastName;
}
// foo(); --> john doe

Можно ли указать только второй необязательный параметр?

Пример:

foo($lastName='smith'); // output: john smith
4b9b3361

Ответ 1

PHP не поддерживает именованные параметры для самих функций. Однако есть несколько способов обойти это:

  • Используйте массив как единственный аргумент для функции. Затем вы можете вывести значения из массива. Это позволяет использовать именованные аргументы в массиве.
  • Если вы хотите разрешить дополнительное число аргументов в зависимости от контекста, то вы можете использовать func_num_args и func_get_args вместо указания действительных параметров в определении функции. Затем, основываясь на количестве аргументов, строковых длинах и т.д., Вы можете определить, что делать.
  • Передайте нулевое значение любому аргументу, который вы не хотите указывать. Не совсем обойти это, но он работает.
  • Если вы работаете в контексте объекта, вы можете использовать магический метод __call() для обработки этих типов запросов, чтобы вы могли маршрутизировать в частные методы на основе того, какие аргументы были переданы.

Ответ 2

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

function foo($arguments) {
  $defaults = array(
    'firstName' => 'john',
    'lastName' => 'doe',
  );

  $arguments = array_merge($defaults, $arguments);

  echo $arguments['firstName'] . ' ' . $arguments['lastName'];
}

Использование:

foo(array('lastName' => 'smith')); // output: john smith

Ответ 3

Вы можете немного изменить свой код:

function foo($firstName = NULL, $lastName = NULL)
{
    if (is_null($firstName))
    {
        $firstName = 'john';
    }
    if (is_null($lastName ))
    {
        $lastName = 'doe';
    }

    echo $firstName . " " . $lastName;
}

foo(); // john doe
foo('bill'); // bill doe
foo(NULL,'smith'); // john smith
foo('bill','smith'); // bill smith

Ответ 4

Если у вас есть несколько необязательных параметров, одно решение должно передать один параметр, который является хэш-массивом:

function foo(array $params = array()) {
    echo $params['firstName'] . " " . $params['lastName'];
}

foo(array('lastName'=>'smith'));

Конечно, в этом решении нет подтверждения того, что поля хэш-массива присутствуют или правильно написаны. Все, что вам нужно, чтобы проверить.

Ответ 5

Нет. Обычный способ сделать это - с некоторыми эвристиками, чтобы определить, какой параметр подразумевается, например длина строки, ввод текста и т.д.

Вообще говоря, вы должны написать функцию, чтобы принимать параметры в порядке, требуемом для наименее требуемого.

Ответ 6

Как вы хотите: нет.

Вы можете использовать некоторую специальную метку, например NULL, чтобы отметить, что это значение не указано:

function foo($firstName, $lastName = 'doe') {
    if (is_null($firstName))
        $firstName = 'john';
    echo $firstName . " " . $lastName;
}

foo(null, 'smith');

Ответ 7

Существует несколько реализаций стиля опций, упомянутых здесь. Пока что они не являются пуленепробиваемыми, если вы планируете использовать их как стандартные. Попробуйте этот шаблон:

function some_func($required_parameter, &$optional_reference_parameter = null, $options = null) {
    $options_default = array(
        'foo' => null,
    );
    extract($options ? array_intersect_key($options, $options_default) + $options_default : $options_default);
    unset($options, $options_default);

    //do stuff like
    if ($foo !== null) {
        bar();
    }
}

Это дает вам функционально-локальные переменные (просто $foo в этом примере) и предотвращает создание любых переменных, которые не имеют значения по умолчанию. Таким образом, никто не может случайно перезаписать другие параметры или другие переменные внутри функции.

Ответ 8

Я хочу, чтобы это решение было на SO, когда я начал использовать PHP 2,5 года назад. Он отлично работает в примерах, которые я создал, и я не понимаю, почему он не должен быть полностью расширяемым. Он предлагает следующие преимущества по сравнению с предлагаемыми ранее:

(i) весь доступ к параметрам внутри функции осуществляется по именованным переменным, как если бы параметры были полностью объявлены, а не требовал доступа к массиву

(ii) очень быстро и легко адаптировать существующие функции

(iii) для любой функции требуется только одна строка дополнительного кода (в дополнение к неизбежной необходимости определять ваши параметры по умолчанию, которые вы будете делать в сигнатуре функции в любом случае, но вместо этого вы определяете их в массиве). Кредит на дополнительную линию полностью связан с Биллом Карвином. Эта строка идентична для каждой функции.

Метод

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

Объявите свои необязательные параметры как локальные переменные

The crux: замените предварительно объявленное значение по умолчанию любых необязательных параметров, используя те, которые вы прошли через массив.

extract(array_merge($arrDefaults, array_intersect_key($arrOptionalParams, $arrDefaults)));

Вызвать функцию, передать ее обязательные параметры, и только те дополнительные параметры, которые вам нужны

Например,

function test_params($a, $b, $arrOptionalParams = array()) {

$arrDefaults = array('c' => 'sat',

                     'd' => 'mat');

extract(array_merge($arrDefaults, array_intersect_key($arrOptionalParams, $arrDefaults)));

echo "$a $b $c on the $d";

}

а затем вызовите его следующим образом

test_params('The', 'dog', array('c' => 'stood', 'd' => 'donkey'));
test_params('The', 'cat', array('d' => 'donkey'));
test_params('A', 'dog', array('c' => 'stood'));

Результаты:

Собака стояла на ослике

Кошка сидела на ослике

На коврике стояла собака

Ответ 9

Аргументы должны передаваться по порядку по положению, вы не можете пропустить параметр как таковой; вам нужно будет указать значение параметра по умолчанию, чтобы пропустить его. Возможно, это побеждает цель того, чего вы пытаетесь достичь.

Без перезаписи вашей функции, чтобы принимать параметры по-разному, здесь можно использовать способ вызова времени:

$func = 'foo';
$args = ['lastName' => 'Smith'];

$ref = new ReflectionFunction($func);
$ref->invokeArgs(array_map(function (ReflectionParameter $param) use ($args) {
    if (array_key_exists($param->getName(), $args)) {
        return $args[$param->getName()];
    }
    if ($param->isOptional()) {
        return $param->getDefaultValue();
    }
    throw new InvalidArgumentException("{$param->getName()} is not optional");
}, $ref->getParameters()));

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

call_func_with_args_by_name('foo', ['lastName' => 'Smith']);

Ответ 10

Если это используется очень часто, просто определите новую специализированную функцию:

function person($firstName = 'john', $lastName = 'doe') {
    return $firstName . " " . $lastName;
}

function usualFirtNamedPerson($lastName = 'doe') {
    return person('john', $lastName);
}

print(usualFirtNamedPerson('smith')); --> john smith

Обратите внимание, что вы также можете изменить значение по умолчанию $lastname в этом процессе.

Когда новая функция оценивается по-разному, просто вызовите функцию со всеми параметрами. Если вы хотите сделать это более понятным, вы можете преподать свои литералы в переменной fin или использовать комментарии.

$firstName = 'Zeno';
$lastName = 'of Elea';
print(person($firstName, $lastName));
print(person(/* $firstName = */ 'Bertrand', /* $lastName = */ 'Russel'));

Хорошо, это не так коротко и элегантно, как person($lastName='Lennon'), но похоже, что вы не можете иметь его в PHP. И это не самый сексуальный способ кодировать его, с супер-метапрограммирующим трюком и т.д., Но какое решение вы бы предпочли встретить в процессе обслуживания?

Ответ 11

Нет, нет, но вы можете использовать массив:

function foo ($nameArray) {
    // Work out which values are missing?
    echo $nameArray['firstName'] . " " . $nameArray['lastName'];
}

foo(array('lastName'=>'smith'));

Ответ 12

К сожалению, то, что вы пытаетесь сделать, не имеет "синтаксического сахара". Все они разные формы WTF.

Если вам нужна функция, которая принимает число undefined произвольных параметров,

function foo () { 
     $args = func_get_args(); 
     # $args = arguments in order 
}

Будет делать трюк. Старайтесь не использовать его слишком много, потому что для Php это немного на магической стороне.

Затем вы можете при желании применить умолчания и делать странные вещи на основе количества параметров.

function foo(){ 
   $args = func_get_args();
   if( count($args) < 1 ){ 
       return "John Smith"; 
   }
   if( count($args) < 2 ) { 
       return "John " .$args[0];
   }
   return $args[0] . " " . $args[1];
}

Кроме того, вы можете дополнительно эмулировать параметры стиля Perl,

function params_collect( $arglist ){ 
    $config = array();
    for( $i = 0; $i < count($arglist); $i+=2 ){ 
       $config[$i] = $config[$i+1];
    }
    return $config; 
}
function param_default( $config, $param, $default ){ 
    if( !isset( $config[$param] ) ){ 
           $config[$param] = $default;
    }
    return $config;
}

function foo(){ 
   $args = func_get_args();
   $config = params_collect( $args ); 
   $config = param_default( $config, 'firstname' , 'John' ); 
   $config = param_default( $config, 'lastname' ,  'Smith' ); 
   return $config['firstname'] . '  ' . $config['lastname'];   
}

foo( 'firstname' , 'john', 'lastname' , 'bob' ); 
foo( 'lastname' , 'bob', 'firstname', 'bob' ); 
foo( 'firstname' , 'smith'); 
foo( 'lastname', 'john' );

Конечно, было бы проще использовать аргумент массива здесь, но вам разрешено иметь выбор (даже плохие способы) делать что-то.

отметим, что это лучше в Perl, потому что вы можете сделать только foo (firstname = > 'john');Суб >