2010-06-25 27 views
79
Strict Standards: Declaration of childClass::customMethod() should be compatible with that of parentClass::customMethod() 

Quelles sont les causes possibles de cette erreur en PHP? Où puis-je trouver des informations sur ce que cela signifie d'être compatible?La déclaration des méthodes doit être compatible avec les méthodes parentes en PHP

+0

notJim l'a tout à fait raison. @ waiwai933, si vous pouviez poster les en-têtes (juste la première ligne: 'function customMethod (...)') pour chaque fonction nous pourrions vous dire le problème spécifique – nickf

+0

Plus de détails sur le message d'erreur et les implications PHP: https: //bugs.php.net/bug.php?id=46851 – hakre

+0

duplicata possible de [Strict Standards: Déclaration de '' devrait être compatible avec ''] (http://stackoverflow.com/questions/17234259/strict-standards -declaration-of-should-be-compatible-with) –

Répondre

103

childClass::customMethod() a différents arguments, ou un niveau d'accès différent (public/privé/protégé) que parentClass::customMethod().

+0

probablement parce que la _visibilité_, la signature des méthodes n'est pas un problème dans PHP –

+39

Ayant les mêmes valeurs par défaut d'argument exact est également important. Par exemple, 'parentClass :: customMethod ($ thing = false)' et 'childClass :: customMethod ($ thing)' déclencheraient l'erreur, car la méthode de l'enfant n'a pas défini de valeur par défaut pour le premier argument. – Charles

+1

Je crois que la visibilité est en fait une erreur différente. D'ailleurs, dans ma boutique, nous n'utilisons pas le mode strict, à cause de cela (nous utilisons E_ALL, IIRC). – notJim

28

Ce message signifie qu'il existe certains appels de méthodes possibles qui peuvent échouer au moment de l'exécution. Supposons que vous ayez

class A { public function foo($a = 1) {;}} 
class B extends A { public function foo($a) {;}} 
function bar(A $a) {$a->foo();} 

Le compilateur ne vérifie que l'a- $ d'appel> foo() par rapport aux exigences de A :: foo() qui ne nécessite aucun paramètre. $ a peut cependant être un objet de classe B qui nécessite un paramètre et donc l'appel échouerait à l'exécution.

Cela peut cependant jamais échouer et ne déclenche pas l'erreur

class A { public function foo($a) {;}} 
class B extends A { public function foo($a = 1) {;}} 
function bar(A $a) {$a->foo();} 

donc pas de méthode peut avoir des paramètres plus nécessaires que sa méthode mère.

Le même message est également généré lorsque les indications de type ne correspondent pas, mais dans ce cas PHP est encore plus restrictif. Cela donne une erreur:

class A { public function foo(StdClass $a) {;}} 
class B extends A { public function foo($a) {;}} 

tout comme ceci:

class A { public function foo($a) {;}} 
class B extends A { public function foo(StdClass $a) {;}} 

qui semble plus restrictive qu'il doit être et je suppose est dû à internals.

Les différences de visibilité provoquent une erreur différente, mais pour la même raison fondamentale. Aucune méthode ne peut être moins visible que sa méthode parente.

+2

dans votre dernier exemple - il ne devrait pas y avoir d'erreur ici parce qu'il est légitime, stdClass $ a est plus restrictif que mélangé $ a. Y a-t-il un moyen de contourner ceci? je veux dire dans ce cas PHP devrait permettre cela mais il donne toujours une erreur ... – galchen

+2

Votre dernier exemple est de type sécurisé, donc il est certainement "plus restrictif que nécessaire". Cela peut être un cas de programmation de culte car il est en conflit avec le polymorphisme en C++ et en Java http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Contravariant_method_argument_type – Warbo

16

si vous voulez garder la forme POO sans se retourner toute erreur désactivée, vous pouvez aussi:

class A 
{ 
    public function foo() { 
     ; 
    } 
} 
class B extends A 
{ 
    /*instead of : 
    public function foo($a, $b, $c) {*/ 
    public function foo() { 
     list($a, $b, $c) = func_get_args(); 
     // ... 

    } 
} 
+0

J'adorerais utiliser ce hack pour contourner ces problèmes. les erreurs. Je crains qu'il pourrait y avoir une pénalité de performance à cette approche? Je vais faire des recherches, mais si vous avez des ressources pour aider à répondre à cette question, ce serait génial. –

+18

Je pense que c'est très hacky et sale ... –

+0

Selon la situation je suppose. Toujours Oui c'est peut-être un peu hacky, mais c'est php? déjà, parfois cela peut être un beau travail, merci! <@ –

0

Juste pour développer cette erreur dans le contexte d'une interface, si vous êtes de type laissant entendre vos paramètres de fonction comme si :

Interface A

use Bar; 

interface A 
{ 
    public function foo(Bar $b); 
} 

classe B

class B implements A 
{ 
    public function foo(Bar $b); 
} 

Si vous avez oublié d'inclure la déclaration use de votre classe d'exécution (classe B), vous obtiendrez également cette erreur, même si les paramètres de la méthode sont identiques.

-1

Résumé Classe A

abstract class A { 
    function foo(); 
} 

Child B

class B { 
    function foo($a=null, $b=null, $c=null) 
    { 
     //do what you want with the parameters. 
    } 
} 

Instance:

$b = new B(); 
$b->foo(); 
$b->($m, $n, $l); 

Le but est de rendre à la fois le travail bien $b->foo et $b->($m, $n, $l).