2009-10-21 16 views
22

Ho una classe in PHP in questo modo:PHP: Come passare argomenti della classe child __construct() a parent :: __ construct()?

class ParentClass { 
    function __construct($arg) { 
     // Initialize a/some variable(s) based on $arg 
    } 
} 

Ha una classe figlia, come ad esempio:

class ChildClass extends ParentClass { 
    function __construct($arg) { 
     // Let the parent handle construction. 
     parent::__construct($arg); 
    } 
} 

Che cosa succede se, per qualche motivo, il ParentClass bisogno di cambiare per prendere più di un argomento opzionale, che vorrei che la mia classe Child fornisse "just in case"? A meno che non re-codice il ChildClass, prenderà sempre solo l'argomento per il costruttore, e passerà sempre solo quell'argomento.

È una pratica così rara o così cattiva che il caso normale è che una ChildClass non deve necessariamente ereditare da una ParentClass che accetta argomenti diversi?

In sostanza, ho visto in Python dove è possibile passare un numero potenzialmente sconosciuto di argomenti a una funzione tramite somefunction(*args) dove "args" è un array/iterable di qualche tipo. Esiste qualcosa del genere in PHP? O devo refactoring queste classi prima di procedere?

risposta

26

C'è qualcosa di simile in php, anche se un po 'prolisso:

$args = func_get_args(); 
call_user_func_array(array($this, 'parent::__construct'), $args); 
+1

Ciò provoca un loop infinito su PHP 5.4.14 – Hubro

+0

Non funziona se $ indica una classe diversa. – mAsT3RpEE

+5

In 5.5 (forse prima) basta fare: 'call_user_func_array ('parent :: __ construct', func_get_args());'; –

1

Sì, è piuttosto una cattiva pratica eseguire una classe figlio che utilizza diversi argomenti del costruttore dal genitore. Soprattutto in un linguaggio come PHP, dove è mal supportato.

Naturalmente, il modo generico di passare una serie di "qualunque argomenti che potremmo desiderare" in PHP è quello di passare un solo argomento costituito da una matrice di valori di configurazione.

+1

Naturalmente, ci avete il "Magic Contenitore "codice odore (http://c2.com/cgi/wiki?MagicContainer). Quello di cui hai bisogno è un oggetto Parameter (http://c2.com/cgi/wiki?ParameterObject). –

+0

Il contenitore magico è purtroppo ampiamente usato nelle applicazioni PHP, comunque. – soulmerge

1

Partenza queste funzioni su php.net:

func_get_args 
func_num_args 

Inoltre, se si vuole fare un argomento opzionale , si può fare questo:

class ParentClass { 
    function __construct($arg, $arg2="Default Value") { 
     // Initialize a/some variable(s) based on $arg 
    } 
} 
-5
parent::__construct(func_get_args()); 
+0

Hm, non _non_ mantiene gli argomenti in ordine (li getta in una matrice solo nel primo argomento). – Wrikken

8

se si ottiene php nidificato errore limite, provate questo:

$args = func_get_args(); 
call_user_func_array(array('parent', '__construct'), $args); 
+0

fonte: http://nl3.php.net/manual/en/function.call-user-func-array.php # 94993 –

+1

Questo lavoro e non introduce il ciclo infinito. –

13

Questo può essere fatto in PHP> = 5.6 senza call_user_func_array() utilizzando il ... (splat) operator:

public function __construct() 
{ 
    parent::__construct(...func_get_args()); 
} 
+0

Ottima soluzione e grazie per aver segnalato il requisito php 5.6! – Philipp

+0

Questo è il mio modo preferito :) Stavo per postarlo fino a quando ho notato che avevi. – LeonardChallis

Problemi correlati