2009-04-13 13 views
104

Mi sembra di ricordare che in PHP esiste un modo per passare un array come elenco di argomenti per una funzione, dereferenziare la matrice nel modo standard func($arg1, $arg2). Ma ora mi sono perso su come farlo. Ricordo il modo di passare per riferimento, come impostare i parametri "glob" in entrata ... ma non come de-listare la matrice in una lista di argomenti.Passare una matrice come argomenti, non come una matrice, in PHP

Può essere semplice come func(&$myArgs), ma sono abbastanza sicuro che non lo è. Ma, purtroppo, il manuale di php.net non ha divulgato nulla finora. Non che abbia dovuto usare questa particolare funzionalità per l'ultimo anno o giù di lì.

risposta

74

noti inoltre che se si desidera applicare un metodo di istanza a un array, è necessario passare la funzione come:

call_user_func_array(array($instance, "MethodName"), $myArgs); 
+4

@understack L'esempio '$ foo-> bar()' sulla [pagina collegata] (http://www.php.net/ manual/en/function.call-user-func-array.php) suggerisce che dovrebbe essere 'array ($ instance," MethodName ")'. –

+11

Impressionante, l'ho usato per evitare la duplicazione degli argomenti del costruttore in una classe figlia :) 'call_user_func_array (array (parent," __construct "), func_get_args());' – Jason

9

Per ragioni di completezza, come di PHP 5.1 funziona anche:

<?php 
function title($title, $name) { 
    return sprintf("%s. %s\r\n", $title, $name); 
} 
$function = new ReflectionFunction('title'); 
$myArray = array('Dr', 'Phil'); 
echo $function->invokeArgs($myArray); // prints "Dr. Phil" 
?> 

See: http://php.net/reflectionfunction.invokeargs

Per i metodi si utilizza invece ReflectionMethod::invokeArgs e si passa l'oggetto come primo parametro.

+0

Questo è effettivamente quello che stavo cercando! – Dejv

65

As has been mentioned, come di PHP 5.6+ è anche possibile utilizzare il ... Token (alias "operatore di splat") come parte della funzionalità funzioni variadic (see here for more info)

<?php 
$array = ['Hello', 'World']; 

function variadic($arg1, $arg2) 
{ 
    // Do stuff 
    echo $arg1.' '.$arg2; 
} 

// Splat $array in function call 
variadic(...$array); 

// Will echo 'Hello World' 

Nota: elementi di matrice sono mappati a argomenti in base alla loro posizione nell'array, non alle loro chiavi.

EDIT

Come per il commento di CarlosCarucce, argomento disimballaggio (come mostrato sopra) è il metodo più veloce di gran lunga in tutti i casi. In alcuni casi, è oltre 5 volte più veloce di call_user_func_array.

ANCHE

Perché credo che questo è davvero utile (anche se non direttamente legati alla questione): si può type-hint the splat operator parameter nella tua definizione di funzione per assicurarsi che tutti i valori passati corrispondono un tipo specifico.

(Basta ricordare che facendo questo MUST essere il parametro ultima si definisce e che fasci tutti i parametri passati alla funzione nella matrice.)

Questo è grande per fare in modo un array contiene articoli di un tipo specifico:

<?php 

// Define the function... 

function variadic(SomeClass ...$items) 
{ 
    // All items will be of type `SomeClass` 
    foreach ($items as $item) { 
     $item->someClassInstanceMethod(); 
    } 
} 

// Then call... 

variadic(new SomeClass, new SomeClass); 

// OR 

$items = [ 
    new SomeClass, 
    new SomeClass, 
]; 

variadic(...$items); 
+5

Questo ha un notevole miglioramento delle prestazioni rispetto a 'call_user_func_array'. Quindi, se stai usando php 5.6+, consiglierei questo. [Ecco un test] (https://gist.github.com/nikic/6390366), che è stato citato nel [php wiki ufficiale] (https://wiki.php.net/rfc/argument_unpacking) – CarlosCarucce