Уровень доступа к определенному классу должен быть общедоступной ошибкой в ​​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));
        }
    }

для целей проверки, но он продолжал выдавать мне эту ошибку

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

Но переменная экземпляра в этом классе $_errors объявлена ​​общедоступной, я не понимаю, почему я получаю эту ошибку.


person user962206    schedule 25.06.2012    source источник


Ответы (5)


Вы получаете эту ошибку, потому что видимость метода должна быть такой же или менее ограничивающей, чем его определение в родительском классе. В этом случае у вас есть addErrors как public в вашем абстрактном классе, и вы пытаетесь сделать его protected в дочернем классе.

person prodigitalson    schedule 25.06.2012

Как уже упоминалось, вы не можете сделать метод подкласса более строгим, чем родительский; это потому, что подклассы должны быть допустимой заменой для их родительского класса.

В вашем конкретном случае я бы изменил видимость всех методов и свойств, начинающихся с подчеркивания, на protected.

person Ja͢ck    schedule 25.06.2012
comment
Почему это так? Рассмотрим древовидную структуру. У него будут классы Node и Leaf, где Leaf является частным случаем Node, таким образом, class Leaf extends Node. Теперь у Node есть function addChild($child). Очевидно, я не хочу допускать function addChild($child) в Leaf. Естественный способ - сделать его закрытым (в то время как в родительском классе он общедоступен), чтобы к нему нельзя было получить доступ. Или я должен унаследовать Node от Leaf ?? :-о - person sumid; 21.11.2013
comment
@sumid нет, если вы не хотите этого, вы просто сгенерируете исключение. - person Ja͢ck; 21.11.2013

Вы указали protected доступ к protected function _addErrors(array $errors) методу Form_Element_Validators класса. Так что измените его на общедоступный.

Редактировать:

Вы заметили? Метод подкласса (переопределенный метод) определяется с помощью подсказки типа. Пожалуйста, оставьте один и тот же тип параметра для обоих; метод суперкласса и подкласса.

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

        public function _addErrors(array $message){
            $this->_errors = $message;
        }
        ....
person kv-prajapati    schedule 25.06.2012
comment
Я уже изменил его тип доступа на общедоступный, но это дало мне еще одну ошибку: Строгие стандарты: объявление Form_Element_Validators::_addErrors() должно быть совместимо с объявлением Validator::_addErrors() в C:\xampp\htdocs\beatbeast\includes\ Db\Validator.php в строке 91 - person user962206; 25.06.2012
comment
@user: Это потому, что ваше определение abastract имеет message в качестве аргумента, а затем в вашем классе Form_Element_Validator вы намекнули, что аргумент является array, либо удалите подсказку типа array из метода-потомка, либо добавьте ее к родителю. - person prodigitalson; 25.06.2012

Начиная с PHP 7.2.0 исправлена ​​ошибка #61970 (Ограничение уровня доступа __construct() в подклассе дает фатальную ошибку).

Увеличьте версию PHP до 7.2, и вы сможете сделать ее private или protected.

person Sergey Podgornyy    schedule 04.06.2019

Это также происходит, когда вы пытаетесь что-то сделать с определенной защитой. Можете добавить

 protected $guard = "guard_name";

Добавьте строку выше в свою модель. это решит проблему.

person Akram Chauhan    schedule 08.09.2019