Аргументы PHP переменной длины? - PullRequest
7 голосов
/ 02 января 2011

В Python и других есть специальный синтаксис для списков аргументов переменной длины:

def do_something(*args):
    # do something

do_something(1, 2, 3, 4, 5, ...) # arbitrarily long list

Я читал руководство по PHP, и там говорилось:

PHP 4 и выше имеет поддержку списки аргументов переменной длины в пользовательские функции. Это действительно довольно просто, используя func_num_args (), func_get_arg () и func_get_args () функции.

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

Я получил первую часть. Вы можете передать столько аргументов, сколько захотите, функции, которая не принимает аргументов, а затем получить их в виде массива, используя func_get_args() и т. Д. Однако я не совсем понимаю, о чем говорит вторая часть.

Итак, мой вопрос: есть ли какой-то особый синтаксис для аргументов переменной длины или какая-то лучшая практика, о которой я не знаю? Подход, предлагаемый в руководстве, в лучшем случае кажется хитрым и заставляет вашу функцию выглядеть так, как будто она не принимает аргументов (если я не делаю это неправильно). Не стоит ли мне вообще пытаться использовать эту языковую функцию?

Ответы [ 6 ]

18 голосов
/ 02 января 2011

Вот более реалистичный пример:

function Average()
{
    $result = 0;
    $arguments = func_get_args();

    foreach ($arguments as $argument)
    {
        $result += $argument;
    }

    return ($result / max(1, func_num_args()));
}

Average(1, 2, 3, 4, 5); // 3

Это называется переменная функция .

10 голосов
/ 02 января 2011

В отличие от оператора Python * или ключевого слова C # params, в PHP вам даже не нужно указывать аргументы переменной длины.Когда начинается вторая часть, «Специальный синтаксис не требуется».

Что касается остальной части второго абзаца: если вы хотите указать какие-либо обязательные или не связанные аргументы перед аргументами переменной длины, укажитеони в вашей подписи функции, так что ваша функция может обрабатывать их.Затем, чтобы получить аргументы переменной длины, удалите необходимые переменные из func_get_args(), например, так:

function func($required) {
    // Contains all arguments that come after $required
    // as they were present at call time
    $args = array_slice(func_get_args(), 1);
}

Вам не нужно этого делать (вы все еще можете нарезать фрагмент из func_get_args() и использовать егосоответственно различные элементы), но это делает ваш код более самодокументированным.

7 голосов
/ 10 декабря 2015

Поскольку PHP 5.6 , список переменных можно указать с помощью оператора ....

function do_something($first, ...$all_the_others)
{
    var_dump($first);
    var_dump($all_the_others);
}

do_something('this goes in first', 2, 3, 4, 5);

#> string(18) "this goes in first"
#>
#> array(4) {
#>   [0]=>
#>   int(2)
#>   [1]=>
#>   int(3)
#>   [2]=>
#>   int(4)
#>   [3]=>
#>   int(5)
#> }

Как видите, оператор ... собирает список переменныхаргументов в массиве.

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

function do_something($first, ...$all_the_others)
{
    do_something_else($first, ...$all_the_others);
    // Which is translated to:
    // do_something_else('this goes in first', 2, 3, 4, 5);
}

Поскольку PHP7 , список переменных может быть принудительно установлен на все того же типа.

function do_something($first, int ...$all_the_others) { /**/ }
2 голосов
/ 02 января 2011

Специального синтаксиса для функций аргументов переменной длины не существует.

Просто используйте функции func_num_args () и func_get_args () для получения аргументов.

Пример:

function callMe(){

    if(func_num_args() == 0){
        echo 'No arguments =)';
    }else{
        var_dump(func_get_args());
    }

}
1 голос
/ 02 января 2011

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

function average() { ... }
function average(arg1, arg2, arg3) { ... }

работает идентично, просто во второй версии перечислено 3 аргумента. Вот и все, не пытайтесь читать на странице руководства больше, чем есть.

0 голосов
/ 02 января 2011

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

function any_function($ops=array())
{
}

$ops = array('name'=>1, 'type'=>'simplexml', 'callback'=>...);
...