某些类的访问级别必须是 PHP 中的公共错误

Posted

技术标签:

【中文标题】某些类的访问级别必须是 PHP 中的公共错误【英文标题】:Access Level to certain class must be public error in PHP 【发布时间】:2012-06-26 08:17:57 【问题描述】:

我创建了这个类

<?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 中的实例变量被声明为公共的,我不明白为什么我会收到这个错误。

【问题讨论】:

【参考方案1】:

您收到该错误是因为该方法的可见性必须与其在父类上的定义相同或限制较少。在这种情况下,您在抽象类中将 addErrors 设置为 public,并尝试在子类中使用 protected

【讨论】:

【参考方案2】:

您已指定protected 访问Form_Element_Validators 类的protected function _addErrors(array $errors) 方法。所以改成public吧。

编辑:

你注意到了吗?子类方法(被覆盖的方法)用Type Hinting 定义。请保持两者的参数类型相同;超类和子类方法。

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

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

【讨论】:

我已经将其访问类型更改为公共,但它给了我另一个错误,“严格标准:Form_Element_Validators::_addErrors() 的声明应该与 C 中的 Validator::_addErrors() 的声明兼容: \xampp\htdocs\beatbeast\includes\Db\Validator.php 在第 91 行" @user: 那是因为你的抽象定义有message 作为参数,然后在你的Form_Element_Validator 类中你有类型提示参数是array 要么删除array从后代方法中键入提示,或将其添加到父方法。【参考方案3】:

正如其他人所提到的,您不能使子类方法比父类方法更具限制性;这是因为子类应该是其父类的有效替代品。

在您的特定情况下,我会将以下划线开头的所有方法和属性的可见性更改为 protected

【讨论】:

为什么会这样?考虑一个树结构。它将有NodeLeaf 类,其中LeafNode 的特例,因此class Leaf extends Node。现在Node 有一个function addChild($child)。显然我不想在Leaf 中允许function addChild($child)。自然的方法是将它设置为私有(而在父类中它是公共的),因此它不能被访问。或者我应该从Leaf 继承Node 吗? :-o @sumid 不,如果您不希望这样,您只需抛出异常。【参考方案4】:

自 PHP 7.2.0 以来,修复了一个错误 #61970(在子类中限制 __construct() 访问级别会导致致命错误)。

将您的 PHP 版本升级到 7.2,您可以将其设为 privateprotected

【讨论】:

【参考方案5】:

当你试图用特定的守卫做某事时也会发生这种情况。 你可以添加

 protected $guard = "guard_name";

在您的模型中添加上述行。 这将解决问题。

【讨论】:

以上是关于某些类的访问级别必须是 PHP 中的公共错误的主要内容,如果未能解决你的问题,请参考以下文章

我相信这是 clang++ 中与访问类的公共成员函数有关的错误

PHP 通知抑制;只有某些情况/方法

调整PHP中的错误级别

JavaOO05

C#:为啥我必须在类的变量中使用公共访问修饰符?

公共资源类的封装