2011-09-22 2 views
1

J'ai une classe et un enfant de abstract:PHP extension avec des arguments inconnus

abstract class Cubique_Helper_Abstract { 
    abstract public function execute(); 
} 

class Cubique_Helper_Doctype extends Cubique_Helper_Abstract{ 
    public function execute($type) {} 
} 

Comme vous pouvez le voir, la méthode execute() est commune. Mais le nombre d'arguments peut être différent dans toutes les classes. Comment puis-je garder cette extension avec différents arguments de méthode?

Il est mon erreur actuelle:

Declaration of Cubique_Helper_Doctype::execute() must be compatible 
with that of Cubique_Helper_Abstract::execute() 

Merci je avance.

+0

Vous pouvez obtenir les arguments avec 'func_get_args' au lieu de les définir dans la signature. Ou dans la classe abstraite, vous pouvez définir la méthode pour accepter une valeur, qui est un tableau (associatif). Dans les classes enfant, vous accédez simplement aux clés dont vous avez besoin. –

+0

@stereofrog: Je suis tout à fait d'accord, +1. Pour mon apprentissage, commenteriez-vous ma réponse ci-dessous? A bientôt – chelmertz

Répondre

2
  • Vous pouvez supprimer execute() de l'abstrait, mais vous ne voulez probablement pas faire cela.

  • Vous pouvez également donner un objet de données comme argument, comme ceci:

    class MyOptions { 
        public function getType(){} 
        public function getStuff(){} 
    } 
    
    abstract class Cubique_Helper_Abstract { 
        abstract public function execute(MyOptions $options); 
    } 
    
    class Cubique_Helper_Doctype extends Cubique_Helper_Abstract{ 
        public function execute(MyOptions $options) { 
        $type = $options->getType(); 
        } 
    } 
    
  • Ou, vous pourriez faire dépendre des valeurs dans le constructeur et laisser de l'argument:

    abstract class Cubique_Helper_Abstract { 
        abstract public function execute(); 
    } 
    
    class Cubique_Helper_Doctype extends Cubique_Helper_Abstract{ 
        public function __construct($type) { 
        // since __construct() is not in abstract, it can be different 
        // from every child class, which let's you handle dependencies 
        $this->type = $type; 
        } 
        public function execute() { 
        // you have $this->type here 
        } 
    } 
    

La dernière alternative est mon préféré. De cette façon, vous vous assurez vraiment que vous avez les dépendances et quand il est temps de execute() vous n'avez pas à lui donner d'arguments.


Je pas utiliser func_get_args() puisque vous perdez la trace des dépendances. Exemple:

class Cubique_Helper_Doctype extends Cubique_Helper_Abstract { 
    public function execute() { 
    $args = func_get_args(); 
    $type = $args[0]; 
    $title = $args[1]; 
    $content = $args[2]; 
    // do something, for example 
    echo $type; // will always echo "" if you miss arguments, but you really want a fatal error 
    } 
} 

$d = new Cubique_Helper_Doctype(); 
$d->execute(); 
// this is a valid call in php, but it ruins your application. 
// you **want** it to fail so that you know what's wrong (missing dependencies) 
+0

@stereofrog A bientôt. Je suis d'accord avec vous sur "public" mais "abstract" est utile pour faire des allusions/faire un contrat avec la classe abstraite. J'ai vu votre autre réponse sur le sujet et je pense que votre cas proposé ici (quelque chose comme 'if ($ _ GET ['bla'] == 'bla') $ class = 'BlaClass';' est logique pour certains mais si vous testez vos cours à l'avance, vous sauriez s'ils travaillent ou pas, et vous pouvez toujours bénéficier d'avoir des résumés.Il y a pire, plus difficile à tester, des cas impliqués par ne pas compiler si vous me demandez :) – chelmertz

1

Vous pouvez utiliser func_get_arg pour que la signature de la méthode de la classe enfant soit la même.

1

Lorsque le nombre d'arguments est différent, vous recevez l'erreur:

Fatal error: Declaration of Cubique_Helper_Doctype::execute() must be compatible with that of Cubique_Helper_Abstract::execute() in C:\wamp\www\tests\41.php on line 16 

Ainsi, votre seule option est de faire le arguement un tableau et passer en elle les arguments réels ou faire la déclaration de execute sans paramètres et mamipuler les arguments envoyés avec func_get_args ou func_get_arg et func_num_args

3

vous pouvez faire une méthode ou une fonction sans argument limité.

function test(){ 
$num = func_num_args(); 
for ($i = 0;$i < $num;$i++) 
{ 
    $arg[$i] = func_get_arg($i); 
} 
    // process on arguments 
} 
Questions connexes