Access Level to certain class must be public error in PHP

18,039

Solution 1

Youre getting that error because the visibility of the method must be the same or less restrictive than that of it its definition on a parent class. In this case you have addErrors as public on your abstract class and are attempting to make it protected on a child class.

Solution 2

As others have mentioned, you can't make a sub class method more restrictive than the parent; this is because sub classes are supposed to be a valid replacement for their parent class.

In your particular case, I would change the visibility of all methods and properties that start with an underscore to protected.

Solution 3

You've specify the protected access to the protected function _addErrors(array $errors) method of Form_Element_Validators class. So change it to public.

Edit:

Have you noticed? The sub class method (overridden method) is defined with Type Hinting. Please keep the same parameter type for both; super-class and sub-class method.

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

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

Solution 4

Since PHP 7.2.0 there was a bug #61970 fixed (Restraining __construct() access level in subclass gives a fatal error).

Bump your PHP version to 7.2 and you could make it private or protected.

Share:
18,039
user962206
Author by

user962206

Updated on June 09, 2022

Comments

  • user962206
    user962206 almost 2 years

    I created this class

    <?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));
            }
        }
    

    for Validation purposes, but it kept giving me this 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
    

    But the instance variable in this class $_errors is declared public, I don't get it why I am receiving this error.

  • user962206
    user962206 almost 12 years
    I already changed its access type to public but it gave me another error, "Strict Standards: Declaration of Form_Element_Validators::_addErrors() should be compatible with that of Validator::_addErrors() in C:\xampp\htdocs\beatbeast\includes\Db\Validator.php on line 91"
  • prodigitalson
    prodigitalson almost 12 years
    @user: Thats because your abastract definition has message as the argument, and then in your Form_Element_Validator class you have type hinted that the argument is an array either remove the array type hint from the descendent method, or add it to the parent.
  • sumid
    sumid over 10 years
    Why it is so? Consider a tree structure. It will have classes Node and Leaf, where Leaf is special case of Node, thus class Leaf extends Node. Now Node has a function addChild($child). Obviously I don't want to allow function addChild($child) in Leaf. The natural way is to set it private (while in parent class it's public) so it cannot be accessed. Or shall I inherit Node from Leaf ?? :-o
  • Ja͢ck
    Ja͢ck over 10 years
    @sumid no, if you don't want that you would simply throw an exception.