Як передавати змінну кількість аргументів функції PHP


115

У мене є функція PHP, яка приймає змінну кількість аргументів (використовуючи func_num_args()та func_get_args()), але кількість аргументів, які я хочу передати функції, залежить від довжини масиву. Чи є спосіб викликати функцію PHP зі змінною кількістю аргументів?


1
Перевірте свою відповідь , щоб дізнатися про знак оператора в новому php5.6: stackoverflow.com/a/23163963/1090562
Сальвадор Далі

Відповіді:


132

Якщо у вас є аргументи в масиві, вас може зацікавити call_user_func_arrayфункція.

Якщо кількість аргументів, які ви хочете передати, залежить від довжини масиву, це, ймовірно, означає, що ви можете самі їх упакувати в масив - і використовувати його для другого параметра call_user_func_array.

Елементи цього масиву, який ви передаєте, будуть отримані вашою функцією як окремі параметри.


Наприклад, якщо у вас є ця функція:

function test() {
  var_dump(func_num_args());
  var_dump(func_get_args());
}

Ви можете запакувати свої параметри в масив, наприклад:

$params = array(
  10,
  'glop',
  'test',
);

А потім викличте функцію:

call_user_func_array('test', $params);

Цей код буде результатом:

int 3

array
  0 => int 10
  1 => string 'glop' (length=4)
  2 => string 'test' (length=4)

тобто 3 параметри; точно так само, якщо функцію називали так:

test(10, 'glop', 'test');

1
Так дякую. call_user_func_array () - саме та функція, яку я шукав.
nohat

Чи можливо використовувати call_user_func_array () для виклику об'єктного методу?
nohat

6
@nohat: ласкаво просимо :-) ;; про використання методу об’єкта: так, ви можете, використовуючи щось на зразок масиву ($ obj, 'methodName') як перший параметр ;; насправді ви можете передавати будь-який «зворотний дзвінок», який хочете, до цієї функції. Для отримання додаткової інформації про зворотні дзвінки дивіться сторінку php.net/callback#language.types.callback
Pascal MARTIN

58

Тепер це можливо за допомогою PHP 5.6.x , використовуючи оператор ... (також відомий як оператор splat в деяких мовах):

Приклад:

function addDateIntervalsToDateTime( DateTime $dt, DateInterval ...$intervals )
{
    foreach ( $intervals as $interval ) {
        $dt->add( $interval );
    }
    return $dt;
}

addDateIntervaslToDateTime( new DateTime, new DateInterval( 'P1D' ), 
        new DateInterval( 'P4D' ), new DateInterval( 'P10D' ) );

1
Надрукував список змінних аргументів є функцією , представленої в PHP 7 .
Даніеле Орландо

46

У новому Php 5.6 ви можете використовувати ... operatorзамість цього func_get_args().

Отже, використовуючи це, ви можете отримати всі параметри, які ви проходите:

function manyVars(...$params) {
   var_dump($params);
}

3
Більше інформації тут: php.net/manual/en/…
fracz

З посилання @fracz, ОП намагається створити "варіативну функцію".
Натан Артур

40

Оскільки 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);
}

Оскільки PHP 7 , змінна список аргументів може бути змушений бути все одного і того ж типу теж.

function do_something($first, int ...$all_the_others) { /**/ }

11

Для тих, хто шукає спосіб зробити це за допомогою $object->method:

call_user_func_array(array($object, 'method_name'), $array);

Я мав успіх з цим у функції конструкта, яка викликає змінну method_name зі змінними параметрами.


2
Також можна скористатися$object->method_name(...$array);
Йоанн Кергалл

Якщо ви хочете пройти далі, скористайтеся$object->method_name(&...$args);
Хаддаді,

4

Ви можете просто назвати це.

function test(){        
     print_r(func_get_args());
}

test("blah");
test("blah","blah");

Вихід:

Масив ([0] => бла) Масив ([0] => бла [1] => бла)


Якщо я правильно розумію ОП, проблема полягає не в отриманні параметрів, а в викликанні функції зі змінною кількістю параметрів.
Паскаль МАРТИН

1
Тоді я не правильно зрозумів ОП. Тоді, безперечно, буде масив. Потім знову, він міг просто передати масив безпосередньо в test (), ні?
Donnie C

1
Передача масиву також може бути вирішенням - якщо я правильно зрозумів ^^
Паскаль MARTIN

1
Старе питання, але fyi, масив працює добре, але передача фактичних аргументів дозволяє використовувати значення за замовчуванням PHP для нульових аргументів, що дозволяє економити багато некрасивих перевірок, щоб побачити, чи містить масив конкретні значення.
Ендофаг

2

Я здивований, що тут ніхто не згадав про проходження та вилучення масиву. Наприклад:

function add($arr){
    extract($arr, EXTR_REFS);
    return $one+$two;
}
$one = 1;
$two = 2;
echo add(compact('one', 'two')); // 3

Звичайно, це не забезпечує перевірку аргументів . Для цього кожен може використовувати мою функцію очікування: https://gist.github.com/iautomation/8063fc78e9508ed427d5


1

Я давнє запитання, я знаю, але жоден з відповідей тут справді не робить гарної роботи просто відповісти на питання.

Я просто розігрувався з php, і рішення виглядає приблизно так:

function myFunction($requiredArgument, $optionalArgument = "default"){
   echo $requiredArgument . $optionalArgument;
}

Ця функція може виконувати дві речі:

Якщо його викликається лише необхідним параметром: myFunction("Hi") він надрукує "Привіт за замовчуванням"

Але якщо він викликається з необов'язковим параметром: myFunction("Hi","me") він надрукує "Привіт мені";

Я сподіваюся, що це допоможе кожному, хто шукає цього в дорозі.


2
Ви не зрозуміли питання. ОП запитував про аргументи, які йому не потрібно було чітко визначати у підписі функції - але він все ще може передавати значення як аргументи функції. Наприклад, підпис функції не має жодних аргументів (необов'язковий чи ні), але коли він цього вимагає, ОП може надіслати 45 різних значень як аргументів функції.
a20

0

Ось рішення за допомогою магічного методу __invoke

(Доступно з php 5.3)

class Foo {
    public function __invoke($method=null, $args=[]){
        if($method){
            return call_user_func_array([$this, $method], $args);
        }
        return false;
    }

    public function methodName($arg1, $arg2, $arg3){

    }
}

Зсередини того ж класу:

$this('methodName', ['arg1', 'arg2', 'arg3']);

З примірника об'єкта:

$obj = new Foo;
$obj('methodName', ['arg1', 'arg2', 'arg3'])

В основному це використовується, call_user_func_arrayяк зазначено у відповіді, проголосованій вище у 2009 році __invoke.
a20
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.