2009-10-21 6 views
22

J'ai une classe en PHP comme ceci:PHP: Comment passer les arguments __construct() de la classe enfant à parent :: __ construct()?

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

Il a une classe enfant, en tant que tel:

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

Et si, pour une raison quelconque, le ParentClass doit changer pour prendre plus de un argument optionnel, que j'aimerais que ma classe Child fournisse "juste au cas où"? À moins que je ne code de nouveau la ChildClass, cela ne prendra jamais qu'un seul argument au constructeur, et ne passera qu'un seul argument.

Est-ce si rare ou une si mauvaise pratique que le cas habituel est qu'une ChildClass n'aurait pas besoin d'hériter d'une classe parent qui prend des arguments différents? Essentiellement, j'ai vu en Python où vous pouvez passer un nombre potentiellement inconnu d'arguments à une fonction via somefunction(*args) où 'args' est un tableau/itérable d'une certaine sorte. Est-ce que quelque chose comme ça existe en PHP? Ou devrais-je refactoriser ces classes avant de continuer?

Répondre

26

Il y a quelque chose comme ça en php, mais un peu bavard:

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

Cela provoque une boucle infinie sur PHP 5.4.14 – Hubro

+0

Ne fonctionnera pas si $ this pointe vers une classe différente. – mAsT3RpEE

+5

Dans 5.5 (peut-être plus tôt), vous pouvez simplement faire: 'call_user_func_array ('parent :: __ construct', func_get_args());'; –

1

Oui, c'est une mauvaise pratique de créer une classe enfant qui utilise des arguments constructeurs différents du parent. Surtout dans une langue comme PHP où elle est mal supportée.

Bien sûr, le moyen générique de passer un ensemble de "quels que soient les arguments que nous pourrions vouloir" en PHP est de passer un seul argument consistant en un tableau de valeurs de configuration.

+1

Bien sûr, il vous avez le « Magic Container "odeur de code (http://c2.com/cgi/wiki?MagicContainer). Ce dont vous avez besoin est un objet de paramètre (http://c2.com/cgi/wiki?ParameterObject). –

+0

Le conteneur magique est malheureusement largement utilisé dans les applications PHP, néanmoins. – soulmerge

1

Découvrez ces fonctions sur php.net:

func_get_args 
func_num_args 

En outre, si vous voulez faire un argument optionnel , vous pouvez le faire:

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

Hm, ne conserve pas les arguments dans l'ordre (les jette juste dans un tableau dans le premier argument). – Wrikken

8

si vous obtenez l'erreur limite imbriquée php, essayez ceci:

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

source: http://nl3.php.net/manual/fr/fonction.call-user-func-array.php # 94993 –

+1

Ce travail et ne présente pas la boucle infinie. –

13

Cela peut se faire en PHP> = 5.6 sans call_user_func_array() en utilisant le ... (splat) operator:

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

Grande solution et merci de souligner l'exigence php 5.6! – Philipp

+0

Ceci est ma façon préférée :) Étais sur le point de le poster jusqu'à ce que j'ai remarqué que vous aviez. – LeonardChallis

Questions connexes