2012-06-25 20 views
5

creé esta claseNivel de acceso a cierta clase debe ser público error en PHP

<?php 
    abstract class Validator{ 
     public $_errors = array(); 
     abstract public function isValid($input); 

     public function _addErrors($message){ 
      $this->_errors = $message; 
     } 

     public function getErrors(){ 
      return $this->_errors; 
     } 


     public function getMessage(){ 
      return $this->message; 
     } 
    } 

    class Validator_NoSpaces extends Validator{ 

     public function __construct($value){ 
      $this->isValid($value); 
     } 
     public function isValid($value){ 
       if (preg_match('/\s/', $value)){ 
       $this->_addErrors("Spaces are not allowed"); 
       return false; 
      } 
      return true; 
     }  
    } 

    class Validator_MinimumLength extends Validator{ 

     protected $_minLength; 
     protected $value; 

     public function __construct($value ,$minLength=8){ 
      $this->_minLength = $minLength; 
      $this->value = $value; 
      $this->isValid($value); 
     } 

     public function isValid($input){ 
      if (strlen($input) > $this->_minLength) { 
       return true; 
      }else{ 
       $this->_addErrors("Input must be at least {$this_minLength}"); 
       return false; 
      } 
     } 
    } 

    class Form_Element_Validators extends Validator{ 

     protected $_validators = array(); 

    public function addValidator(Validator $validator) 
    { 
     $this->_validators[] = $validator; 
    } 

    public function getValidators() 
    { 
     return $this->_validators; 
    } 

    protected function _addErrors(array $errors) 
    { 
     foreach ($errors as $error) { 
      $this->_addErrors($error); 
     } 
    } 

    public function hasErrors() 
    { 
     return (count($this->getErrors()) !== 0); 
    } 

    public function isValid($input) 
    { 
     foreach ($this->_validators as $validator) { 
      if (!$validator->isValid($input)) { 
       $this->_addErrors($validator->getErrors()); 
      } 
     } 
     return !$this->hasErrors(); 
    } 

    } 

    class Form_Element extends Form_Element_Validators{ 

     public function __construct($value){ 
       $this->addValidator(new Validator_NoSpaces($value)); 
       $this->addValidator(new Validator_MinimumLength($value)); 
     } 
    } 

para fines de validación, pero me mantuvo dando este error

Fatal error: Access level to Form_Element_Validators::_addErrors() must be public (as in class Validator) in C:\xampp\htdocs\beatbeast\includes\Db\Validators.php on line 91 

Pero la variable de instancia en esta clase $ _errors se declara pública, no entiendo por qué recibo este error.

Respuesta

13

Está obteniendo ese error porque la visibilidad del método debe ser igual o menos restrictiva que su definición en una clase principal. En este caso, tiene addErrors como public en su clase abstracta y está intentando que sea protected en una clase secundaria.

1

Has especificado el acceso protected al método protected function _addErrors(array $errors) de la clase Form_Element_Validators. Así que cámbialo a público.

Editar:

¿Has notado? El método de clase secundaria (método reemplazado) se define con Type Hinting. Por favor, mantenga el mismo tipo de parámetro para ambos; método de superclase y subclase.

abstract class Validator{ 
     public $_errors = array(); 
     abstract public function isValid($input); 

     public function _addErrors(array $message){ 
      $this->_errors = $message; 
     } 
     .... 
+0

Ya cambié su tipo de acceso a público pero me dio otro error, "Normas estrictas: Declaración de Form_Element_Validators :: _ addErrors() debería ser compatible con la de Validator :: _ addErrors() en C: \ xampp \ htdocs \ beatbeast \ includes \ Db \ Validator.php en la línea 91 " – user962206

+1

@user: Eso es porque su definición abastract tiene' message' como argumento, y luego en su clase 'Form_Element_Validator' tiene el tipo insinuado que el argumento es' array' elimine la sugerencia de tipo 'array' del método descendente o agréguela al padre. – prodigitalson

7

Como han mencionado otros, no se puede hacer que un método de subclase sea más restrictivo que el primario; esto se debe a que se supone que las subclases son un reemplazo válido para su clase principal.

En su caso particular, cambiaría la visibilidad de todos los métodos y propiedades que comienzan con un guión bajo al protected.

+0

¿Por qué es así? Considera una estructura de árbol. Tendrá clases 'Node' y' Leaf', donde 'Leaf' es un caso especial de' Node', por lo tanto 'clase Leaf extends Node'. Ahora 'Node' tiene una' función addChild ($ child) '. Obviamente no quiero permitir 'function addChild ($ child)' en 'Leaf'. La forma natural es establecerlo en privado (mientras que en la clase principal es público) por lo que no se puede acceder. ¿O debería heredar 'Node' de' Leaf' ?? : -o – sumid

+1

@sumid no, si no quiere, simplemente lanzará una excepción. –

Cuestiones relacionadas