2010-10-21 11 views
5

C'è un modo per rilevare il numero di argomenti di una funzione in una classe?Ottieni il numero di argomenti per una funzione di classe

Quello che voglio fare è il seguente.

$class = 'foo'; 
$path = 'path/to/file'; 
if (! file_exists($path)) { 
    die(); 
} 

require($path); 

if (! class_exists($class)) { 
    die(); 
} 

$c = new class; 

if (num_function_args($class, $function) == count($url_segments)) { 
    $c->$function($one, $two, $three); 
} 

È possibile?

+0

sicuro. puoi comunque, alla tua definizione di classe, usare qualcosa come func_get_arg() [http://php.net/manual/en/function.func-get-arg.php] e in base agli argomenti ricevuti, fare cose diverse .. – acm

+1

Dovresti considerare un design alternativo. Potresti fornire più contesto al tuo problema? – erisco

+1

Si prega di chiarire se si desidera conoscere il numero di argomenti passati a una funzione in fase di esecuzione, ad es. 'fn (1,1,1)' (3 argomenti) o il numero di argomenti forniti nella firma, ad es. 'function fn ($ a, $ b $ c = 0, $ d = 0)' (4 argomenti, 2 richiesti, 2 facoltativi) – Gordon

risposta

5

Utilizzare la riflessione, ma questo è davvero un sovraccarico nel codice; e un metodo può avere un numero qualsiasi di argomenti senza che vengano esplicitamente definiti nella definizione del metodo.

$classMethod = new ReflectionMethod($class,$method); 
$argumentCount = count($classMethod->getParameters()); 
+0

Non credo che lo userò ma grazie per la risposta. – JasonS

+0

Mentre i metodi di riflessione nella maggior parte delle lingue tendono a costare un numero maggiore di cicli della CPU, sto utilizzando questo metodo esatto e non vedo alcuna differenza nei tempi di esecuzione con o senza. – Cypher

+0

@Cypher Dopo 2 anni e 1/2 di miglioramento in PHP da quando è stata pubblicata questa risposta, Reflection è migliorato in modo significativo –

3

Usa call_user_func_array, invece, se si passa troppi parametri, che viene semplicemente ignorato.

Demo

class Foo { 
    public function bar($arg1, $arg2) { 
     echo $arg1 . ', ' . $arg2; 
    } 
} 


$foo = new Foo(); 

call_user_func_array(array($foo, 'bar'), array(1, 2, 3, 4, 5)); 

uscita sarà

1, 2 

Per gli argomenti dinamici, utilizzare func_get_args come questo:

class Foo { 
    public function bar() { 
     $args = func_get_args(); 
     echo implode(', ', $args); 
    } 
} 


$foo = new Foo(); 

call_user_func_array(array($foo, 'bar'), array(1, 2, 3, 4, 5)); 

uscita sarà

1, 2, 3, 4, 5 
+0

Viene inoltre generato un avviso e passando troppi argomenti utilizzando 'call_user_func_array' a determinate funzioni (come is_numeric) cambierà effettivamente il comportamento di quella funzione. –

+0

@BrianHogg, ovviamente. Poiché gli argomenti passati alle funzioni vengono inviati allo stack, se lo stack è pieno, si avranno comportamenti strani. Se questo dovesse mai essere il tuo caso, il tuo problema non sono i comportamenti della funzione :) Usa un singolo array arg in quel caso, per esempio. –

+0

c'era un problema recente con un CMS popolare in cui una funzione di convalida/filtro stava chiamando 'is_numeric' con 3 parametri (il valore più dettagli sulla richiesta), invece di' is_numeric' guardando il primo argomento e ignorando gli altri restituisce NULL e la validazione fallisce. Non pensare che si tratti di un problema di overflow dello stack (ha ha), ma piuttosto degli altri parametri che influenzano l'output della funzione piuttosto che essere semplicemente ignorati. –

5

Per ottenere il numero di argomenti a una funzione o firma del metodo, è possibile utilizzare

Esempio

$rf = new ReflectionMethod('DateTime', 'diff'); 
echo $rf->getNumberOfParameters();   // 2 
echo $rf->getNumberOfRequiredParameters(); // 1 

Per ottenere il numero di argomenti passati a una funzione a t tempo di esecuzione, è possibile utilizzare

  • func_num_args - Restituisce il numero di argomenti passati alla funzione

Esempio

function fn() { 
    return func_num_args(); 
} 
echo fn(1,2,3,4,5,6,7); // 7 
non
Problemi correlati