【问题标题】:Object-Oriented PHP - __set() cannot access protected attribute [duplicate]面向对象的 PHP - __set() 无法访问受保护的属性
【发布时间】:2013-01-05 15:41:08
【问题描述】:

可能重复:
PHP __get and __set magic methods

刚从 OOP 开始。 .无论如何不确定我是否理解正确但代码不应该因为函数__set()而改变$attribute的值吗?

<?php
class aclass
{
    protected $attribute; //edited from public to protected
    public function __get ($name)
    {
        return $this->$name;    
    }
    public function __set ($name, $value)
    {
        if($name == "foo")
        {
            $this->$name = $value;
        }
    }
} 
$a = new aclass();
$a->attribute = "bar";
echo $a->attribute;
?>

当我运行它时,会显示一条错误消息:

“致命错误:无法访问受保护的属性 aclass::$attribute . . . . . 在第 16 行” 第 16 行是“echo $a->attribute” - 其他帖子说该属性必须设置为 PROTECTED 但它不起作用。我正在使用 PHP 5.4.3 - 有什么想法吗?

【问题讨论】:

  • 您应该检查其他问题,例如stackoverflow.com/questions/4713680/…
  • 这个问题已经被问过很多次了,请在打开问题之前进行长时间的搜索。
  • 如果您刚开始使用 OOP,我建议您将__get__set 留待以后使用;在第一种情况下,它们很有用但不是必须学习的;掌握主要概念,稍后再回到魔术方法。有些人不喜欢它们并坚持编写名为getPropname()setPropname() 的单独方法;这可能是一种更简单的开始方式。此外,即将发布的 PHP 5.5 版将提供更多用于定义属性的语法选项,这意味着对魔术方法的需求将大大减少。
  • 对不起,我正在阅读的书谈到了它,它不是很清楚,它使用了很多,所以我只需要理解它。当我阅读 php 手册时,我更加迷失了。我发布了一个关于它的问题,因为我在搜索时得到的结果对于我正在寻找的内容来说有点太深了。 @Deele 的链接是一个帮助谢谢。也感谢@SDC 的提示!
  • 这与 OOP 无关。它是关于基本语言功能和可见性的。

标签: php visibility


【解决方案1】:

您的__set() 魔术方法只会在尝试访问非公共或未定义属性时调用,但attribute 属性IS 已定义且IS 已公开,所以直接访问。

如果您希望__set() 方法“拦截”对attribute 的访问,则必须将其设为protectedprivate

【讨论】:

  • 它也会触发未定义的属性
  • @Dale 谢谢,答案已更新!
  • 将 $attribute 设置为 protected 或 private 不起作用。它给出了一个错误:“无法访问受保护的属性”。对此有什么想法吗?我去了上面关于同一主题的建议链接,但答案相同,即不将属性设置为公共,而是设置为受保护或私有。我错过了什么?
  • 我刚刚尝试将public $attribute 替换为protected $attribute,它对我来说可以正常工作。
  • 试过了,没有报错,见sandbox.onlinephpfunctions.com/code/…
【解决方案2】:

__set() 当您尝试将值分配给未定义的属性时将被调用。在您的情况下,$attribute 已经用类定义,因此不会调用 __set

【讨论】:

  • 这不是真的。尝试访问私有或受保护属性时将调用它,请参阅 @MatteoTassinari 的 anwser
  • @WouterJ 这其实是真的,应该与其他答案合并
  • @Dale 好的,我有点快。这是正确的,虽然它没有回答问题。我已经删除了我的反对票。
  • @WouterJ 我想知道通过 __set() 执行时新创建的属性的访问级别是什么?嗯...,经过快速测试,它似乎是“公共的”,这很有趣,因为它不能再次通过 __set() 访问,哈哈,PHP
  • @Dale 是的,我刚刚找到了相同的答案。这看起来不正确......
猜你喜欢
  • 2019-10-06
  • 1970-01-01
  • 2013-10-02
  • 1970-01-01
  • 2012-12-28
  • 2014-09-13
  • 1970-01-01
  • 1970-01-01
  • 2013-07-19
相关资源
最近更新 更多