Übergeben einer variablen Anzahl von Argumenten an eine PHP-Funktion

115

Ich habe eine PHP-Funktion, die eine variable Anzahl von Argumenten (mit func_num_args()und func_get_args()) akzeptiert , aber die Anzahl der Argumente, die ich an die Funktion übergeben möchte, hängt von der Länge eines Arrays ab. Gibt es eine Möglichkeit, eine PHP-Funktion mit einer variablen Anzahl von Argumenten aufzurufen ?

nichts
quelle
1
Überprüfen Sie meine Antwort, um mehr über einen Splat-Operator in der neuen Version 5.6
Salvador Dali

Antworten:

132

Wenn Sie Ihre Argumente in einem Array haben, könnte Sie die call_user_func_arrayFunktion interessieren .

Wenn die Anzahl der Argumente, die Sie übergeben möchten, von der Länge eines Arrays abhängt, bedeutet dies wahrscheinlich, dass Sie sie selbst in ein Array packen können - und dieses für den zweiten Parameter von verwenden können call_user_func_array.

Elemente dieses Arrays, die Sie übergeben, werden dann von Ihrer Funktion als eindeutige Parameter empfangen.


Zum Beispiel, wenn Sie diese Funktion haben:

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

Sie können Ihre Parameter wie folgt in ein Array packen:

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

Rufen Sie dann die Funktion auf:

call_user_func_array('test', $params);

Dieser Code gibt die Ausgabe aus:

int 3

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

dh 3 Parameter; genau wie die Funktion wurde so genannt:

test(10, 'glop', 'test');
Pascal MARTIN
quelle
1
Ja Dankeschön. call_user_func_array () ist genau die Funktion, nach der ich gesucht habe.
nohat
Ist es möglich, call_user_func_array () mit einem Objektmethodenaufruf zu verwenden?
nohat
6
@nohat: Gern geschehen :-) ;; über die Verwendung einer Methode eines Objekts: Ja, Sie können so etwas wie Array ($ obj, 'methodName') als ersten Parameter verwenden ;; Tatsächlich können Sie jeden gewünschten "Rückruf" an diese Funktion übergeben. Weitere Informationen zu Rückrufen finden Sie unter php.net/callback#language.types.callback
Pascal MARTIN
58

Dies ist jetzt mit PHP 5.6.x unter Verwendung des Operators ... möglich (in einigen Sprachen auch als Splat-Operator bezeichnet):

Beispiel:

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' ) );
JCM
quelle
1
Die Liste der typisierten Variablenargumente ist eine in PHP 7 eingeführte Funktion .
Daniele Orlando
46

In einem neuen Php 5.6 können Sie ... operatoranstelle von verwenden func_get_args().

Auf diese Weise können Sie alle Parameter abrufen, die Sie übergeben:

function manyVars(...$params) {
   var_dump($params);
}
Salvador Dali
quelle
3
Weitere Infos hier: php.net/manual/en/…
fracz
Über den @ fracz-Link versucht OP, eine "variable Funktion" zu erstellen.
Nathan Arthur
40

Seit PHP 5.6 kann mit dem ...Operator eine variable Argumentliste angegeben werden.

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)
#> }

Wie Sie sehen können, ...sammelt der Operator die variable Liste der Argumente in einem Array.

Wenn Sie die Variablenargumente an eine andere Funktion übergeben müssen, ...kann Ihnen das trotzdem helfen.

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);
}

Seit PHP 7 kann die variable Liste von Argumenten gezwungen werden , sein alle vom gleichen Typ zu.

function do_something($first, int ...$all_the_others) { /**/ }
Daniele Orlando
quelle
11

Für diejenigen, die nach einer Möglichkeit suchen, dies zu tun mit $object->method:

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

Dies gelang mir in einer Konstruktfunktion, die eine Variable method_name mit variablen Parametern aufruft.

Danilo
quelle
2
Sie können auch verwenden$object->method_name(...$array);
Yoann Kergall
Wenn Sie weiter gehen möchten, verwenden Sie$object->method_name(&...$args);
Fabien Haddadi
4

Sie können es einfach nennen.

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

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

Ausgabe:

Array ([0] => bla) Array ([0] => bla [1] => bla)

Donnie C.
quelle
Wenn ich das OP richtig verstehe, besteht das Problem nicht darin, die Parameter zu empfangen, sondern die Funktion mit einer variablen Anzahl von Parametern aufzurufen .
Pascal MARTIN
1
Ich habe das OP also nicht richtig verstanden. Ein Array wäre dann definitiv der richtige Weg. Andererseits konnte er das Array einfach direkt an test () übergeben, oder?
Donnie C
1
Das Übergeben eines Arrays könnte auch eine Lösung sein - wenn ich es richtig verstanden habe ^^
Pascal MARTIN
1
Alte Frage, aber zu Ihrer Information, ein Array funktioniert einwandfrei, aber wenn Sie tatsächliche Argumente übergeben, können Sie die Standardwerte von PHP für Nullargumente verwenden, was eine Menge hässlicher Überprüfungen erspart, um festzustellen, ob das Array bestimmte Werte enthält.
Endophage
1

Eine alte Frage, ich weiß, aber keine der Antworten hier ist wirklich gut darin, einfach die Frage zu beantworten.

Ich habe gerade mit PHP herumgespielt und die Lösung sieht so aus:

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

Diese Funktion kann zwei Dinge tun:

Wenn es nur mit dem erforderlichen Parameter aufgerufen wird: myFunction("Hi") Es wird "Hi default" ausgegeben.

Aber wenn es mit dem optionalen Parameter aufgerufen wird: myFunction("Hi","me") Es wird "Hi me" ausgegeben;

Ich hoffe, das hilft jedem, der dies später sucht.

Alex
quelle
2
Sie haben die Frage nicht verstanden. OP fragte nach Argumenten, die er nicht explizit in der Funktionssignatur definieren musste - dennoch kann er Werte als Argumente an die Funktion übergeben. Beispielsweise sind für die Funktionssignatur keine Argumente definiert (optional oder nicht), aber wenn er dies benötigt, kann OP 45 verschiedene Werte als Argumente an die Funktion senden.
a20
0

Hier ist eine Lösung mit der magischen Methode __invoke

(Verfügbar seit 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){

    }
}

Aus derselben Klasse:

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

Aus einer Instanz eines Objekts:

$obj = new Foo;
$obj('methodName', ['arg1', 'arg2', 'arg3'])
Dieter Gribnitz
quelle
Dies wird im Grunde genommen verwendet, call_user_func_arraywie in der Antwort mit der höchsten Abstimmung im Jahr 2009 angegeben. Vielleicht ist es sinnvoll, ein Extra darum zu wickeln __invoke- aber ich sehe es nicht.
A20