2012-06-25 9 views
5

Ho creato questa classeL'accesso a certa classe deve essere errore di pubblico in 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)); 
     } 
    } 

per scopi di convalida, ma continuava a darmi questo errore

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 

Ma la variabile di istanza in questa classe $ _errors è dichiarato pubblico, non capisco perché sto ricevendo questo errore.

risposta

13

Stai ricevendo quell'errore perché la visibilità del metodo deve essere la stessa o meno restrittiva di quella della sua definizione su una classe genitore. In questo caso hai addErrors come public nella tua classe astratta e stai tentando di renderlo protected in una classe figlio.

1

È stato specificato l'accesso protected al metodo protected function _addErrors(array $errors) della classe Form_Element_Validators. Quindi cambialo in pubblico.

Modifica:

Avete notato? Il metodo sub class (metodo sovrascritto) è definito con Type Hinting. Si prega di mantenere lo stesso tipo di parametro per entrambi; metodo super-classe e sottoclasse.

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

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

Ho già cambiato il suo tipo di accesso in pubblico ma mi ha dato un altro errore, "Strict Standard: Dichiarazione di Form_Element_Validators :: _ addErrors() dovrebbe essere compatibile con quello di Validator :: _ addErrors() in C: \ xampp \ htdocs \ beatbeast \ include \ Db \ Validator.php sulla riga 91 " – user962206

+1

@user: Questo perché la tua definizione di abastract ha' message' come argomento, e quindi nella classe 'Form_Element_Validator' hai scritto che l'argomento è un' array' rimuovere l'hint di tipo 'array' dal metodo discendente o aggiungerlo al genitore. – prodigitalson

7

Come altri hanno già detto, non è possibile rendere un metodo di sottocategoria più restrittivo rispetto al genitore; questo perché le sottoclassi dovrebbero essere un sostituto valido per la loro classe genitore.

Nel tuo caso particolare, cambierei la visibilità di tutti i metodi e le proprietà che iniziano con un trattino basso a protected.

+0

Perché è così? Considera una struttura ad albero. Avrà classi 'Node' e' Leaf', dove 'Leaf' è un caso speciale di' Node', quindi 'classe Leaf estende il Nodo'. Ora 'Nodo' ha una' funzione addChild ($ child) '. Ovviamente non voglio consentire 'function addChild ($ child)' in 'Leaf'. Il modo naturale è impostarlo come privato (mentre nella classe genitore è pubblico) quindi non è possibile accedervi. O erediterò 'Node' da' Leaf' ?? : -o – sumid

+1

@sumid no, se non vuoi che tu possa semplicemente lanciare un'eccezione. –