2012-06-25 14 views
5

Stworzyłem tę klasęDostęp do pewnej klasy musi być błąd publicznego w 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)); 
     } 
    } 

dla celów walidacji, ale trzymane daje mi ten błąd

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 

ale zmienną instancji w tej klasie $ _errors jest ogłoszone publicznie, nie rozumiem dlaczego otrzymuję ten błąd.

Odpowiedz

13

Youre coraz to błąd, ponieważ widoczność tej metody muszą być takie same lub mniej restrykcyjne niż to jej definicja w klasie nadrzędnej. W tym przypadku masz addErrors jako public w klasie abstrakcyjnej i próbujesz uczynić ją protected w klasie potomnej.

1

Podano dostęp protected do klasy protected function _addErrors(array $errors) klasy Form_Element_Validators. Zmień to na publiczne.

Edit:

Czy zauważyliście? Metoda podklasowa (metoda przesłonięta) jest zdefiniowana jako Type Hinting. Zachowaj ten sam typ parametru dla obu; metoda super-klasy i podklasy.

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

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

Już zmieniłem jego typ dostępu na publiczny, ale dał mi kolejny błąd: "Ścisłe standardy: Deklaracja Form_Element_Validators :: _ addErrors() powinny być kompatybilne z Validator :: _ addErrors() w C: \ xampp \ htdocs \ beatbeast \ obejmuje \ Db \ Validator.php on line 91" – user962206

+1

@user: to dlatego, że twoja definicja Sk? ad Abastract ma 'message' jako argument, a następnie w swojej klasie' Form_Element_Validator' masz rodzaj zrozumienia, że ​​argumentem jest 'array' usuń podpowiedź typu "tablica" z metody potomnej lub dodaj ją do rodzica. – prodigitalson

7

Jak wspominają inni, nie można zrobić metoda klasy sub bardziej restrykcyjne niż rodzica; to dlatego, że podklasy powinny być poprawnym zamiennikiem ich klasy macierzystej.

W twoim przypadku zmieniłbym widoczność wszystkich metod i właściwości, które zaczynają się od podkreślenia na protected.

+0

Dlaczego tak się dzieje? Rozważ strukturę drzewa. Będzie miał klasy 'Node' i' Leaf', gdzie 'Leaf' jest szczególnym przypadkiem' Node', a więc 'klasa Leaf extends Node'. Teraz 'Węzeł' ma' funkcję addChild ($ child) '. Oczywiście nie chcę dopuścić 'function addChild ($ child)' w 'Leaf'. Naturalnym sposobem jest ustawienie go jako prywatnego (podczas gdy w klasie rodzica jest to publiczne), więc nie można uzyskać do niego dostępu. Czy powinienem dziedziczyć 'Węzeł' z' Liścia'? : -o – sumid

+1

@sumid nie, jeśli nie chcesz, to po prostu wyrzucisz wyjątek. –