2013-10-23 10 views
15

Nel seguente codice chiamo una classe con call_user_func().controlla se la funzione esiste in classe prima di chiamare call_user_func()

if(file_exists('controller/' . $this->controller . '.controller.php')) { 
    require('controller/' . $this->controller . '.controller.php'); 
    call_user_func(array($this->controller, $this->view)); 
} else { 
    echo 'error: controller not exists <br/>'. 'controller/' . $this->controller . '.controller.php'; 
} 

Diciamo che il controller ha il seguente codice.

class test { 

    static function test_function() { 
     echo 'test'; 
    } 

} 

Quando chiamo call_user_func('test', 'test_function') non ci sono problemi. Ma quando chiamo una funzione che non esiste, non funziona. Ora voglio verificare prima se la funzione nel test di classe esiste, prima chiamo la funzione call_user_func.

Esiste una funzione che verifica se in una classe esiste una funzione o esiste un altro modo in cui posso verificarlo?

+7

[method_exists()] (http://php.net /manual/en/function.method-exists.php) –

+0

Grazie a @MarkBaker! –

+2

Non tutti i metodi esistenti sono richiamabili -> [is_callable] (http://php.net/manual/en/function.is-callable.php) – a4c8b

risposta

39

Stai cercando method_exists per i principianti. Ma ciò che sidovrebbe verificare, anche se il metodo è chiamabile. Questo viene fatto dalla funzione denominata utilmente is_callable:

if (method_exists($this->controller, $this->view) 
    && is_callable(array($this->controller, $this->view))) 
{ 
    call_user_func(
     array($this->controller, $this->view) 
    ); 
} 

Ma questo è solo l'inizio delle cose. Il tuo snippet contiene chiamate esplicite require, il che suggerisce che non stai utilizzando un autoloader.
Inoltre, tutto quello che stai facendo è controllare file_exists, non se la classe era già stata caricata. Il tuo codice genererà quindi un errore fatale se per caso il tuo frammento viene eseguito due volte con gli stessi valori per $this->controller.
Iniziare il fissaggio questo, in meno, cambiare il vostro require-require_once ...

+0

TIL su 'is_callable', grazie! –

+0

Hai bisogno di chiamare 'method_exists()' se stai chiamando 'is_callable()' comunque? – MrWhite

+2

@ w3d: 'is_callable' potrebbe, in teoria, restituire' true' anche se non si sta chiamando un metodo (chiusure assegnate alle proprietà). fare entrambi i controlli è forse un po 'paranoico, ma è il modo più sicuro. Inoltre, l'ultima volta che ho controllato, 'method_exists' ha funzionato meglio, quindi se questo restituisce false,' is_callable' non verrà chiamato (micro-ottimizzazione, lo so, ma ancora ...). Questo non vuol dire che tu non abbia un punto, però, ma immagino che entrambe le funzioni meritino di essere menzionate in questo contesto ... –

9

È possibile utilizzare la funzione php method_exists():

if (method_exists('ClassName','method_name')) 
call_user_func(etc...); 

o anche:

if (method_exists($class_instance,'method_name')) 
call_user_func(etc...); 
+0

Grande È stato fatto capire molto semplice. –

0

Usa method_exists($this->controller, $this->view). Per il tuo esempio:

if(file_exists('controller/' . $this->controller . '.controller.php') && 
    method_exists($this->controller,$this->view)) { 

    require('controller/' . $this->controller . '.controller.php'); 
    call_user_func(array($this->controller, $this->view)); 

} else { 
    echo 'error: controller or function not exists <br/>'. 'controller/' . $this->controller . '.controller.php'; 
} 
+1

Anche se avresti bisogno di chiamare 'method_exists()' _after_ hai incluso il file di classe. – MrWhite

3

da PHP 5.3 è anche possibile utilizzare

if(method_exists($this, $model)) 
    return forward_static_call([$this, $model],$extra, $parameter); 
Problemi correlati