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

¿Cuáles son las posibles causas de este error en PHP? ¿Dónde puedo encontrar información sobre lo que significa ser compatible?La declaración de métodos debe ser compatible con los métodos principales en PHP

+0

notJim lo tiene exactamente. @ waiwai933, si pudieras publicar los encabezados (solo la primera línea: 'function customMethod (...)') para cada función, podríamos contarte el problema específico – nickf

+0

Más detalles sobre el mensaje de error y las implicaciones del tiempo de compilación de PHP: https: //bugs.php.net/bug.php?id=46851 – hakre

+0

posible duplicado de [Normas estrictas: La declaración de '' debería ser compatible con ''] (http://stackoverflow.com/questions/17234259/strict-standards -declaration-of-should-be-compatible-with) –

Respuesta

103

childClass::customMethod() tiene diferentes argumentos, o un nivel de acceso diferente (público/privado/protegido) que parentClass::customMethod().

+0

probablemente es porque la _visibilidad_, firma de métodos no es un problema en PHP –

+39

Tener los mismos valores predeterminados de argumento exacto también es importante. Por ejemplo, 'parentClass :: customMethod ($ thing = false)' y 'childClass :: customMethod ($ thing)' dispararían el error, porque el método del niño no ha definido un valor predeterminado para el primer argumento. – Charles

+1

Creo que la visibilidad es en realidad un error diferente. Por cierto, en mi tienda no usamos el modo estricto, debido a esto (utilizamos E_ALL, IIRC). – notJim

28

Este mensaje significa que hay ciertas llamadas a métodos posibles que pueden fallar en el tiempo de ejecución. Suponga que tiene

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

El compilador sólo comprueba la llamada $ a-> foo() en contra de las exigencias de A :: foo(), que no requiere ningún parámetro. Sin embargo, $ a puede ser un objeto de la clase B que requiere un parámetro y, por lo tanto, la llamada fallará en el tiempo de ejecución.

Sin embargo, esto nunca puede fallar y no provocar el error

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

Así que ningún método puede tener más parámetros requeridos que su método de los padres.

El mismo mensaje también se genera cuando las sugerencias de tipo no coinciden, pero en este caso PHP es aún más restrictivo. Esto da un error:

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

que hace esto:

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

que parece más restrictiva de lo que debe ser y supongo que se debe a componentes internos.

Las diferencias de visibilidad provocan un error diferente, pero por el mismo motivo básico. Ningún método puede ser menos visible que su método principal.

+2

en su último ejemplo: no debería haber un error aquí porque es legítimo, stdClass $ a es más restrictivo que mixto $ a. ¿Hay alguna forma de evitar esto? Quiero decir, en este caso, PHP debería permitir esto, pero todavía da un error ... – galchen

+2

Su último ejemplo es seguro, por lo que sin duda es "más restrictivo de lo necesario". Este puede ser un caso de programación de culto de carga, ya que entra en conflicto con el polimorfismo en C++ y Java http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Contravariant_method_argument_type – Warbo

16

si quiere mantener la forma programación orientada a objetos sin necesidad de encender cualquier error fuera, también puede:

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

Me encantaría utilizar este truco para evitar estos errores Me preocupa que pueda haber una penalización en el rendimiento de este enfoque. Voy a investigar esto, pero si tienes recursos para ayudar a responder esa pregunta, sería genial. –

+18

Creo que esto es muy sucio y sucio ... –

+0

Depende de la situación, supongo. Todavía sí, puede ser un poco hacky, pero es php? ya, a veces eso puede ser un buen trabajo, gracias! <@ –

0

Sólo para ampliar sobre este error en el contexto de una interfaz, si usted es el tipo haciendo alusión a sus parámetros de función como tal :

interfaz A

use Bar; 

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

Clase B

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

Si ha olvidado incluir la declaración use en su clase que implementa (Clase B), entonces también recibirá este error a pesar de que los parámetros del método son idénticos.

-1

Resumen Clase A

abstract class A { 
    function foo(); 
} 

Clase B Niño

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

Instancia:

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

El propósito es hacer bien tanto $b->foo y $b->($m, $n, $l) trabajo.

Cuestiones relacionadas