【问题标题】:Is this a PHP OO bug? [closed]这是一个 PHP OO 错误吗? [关闭]
【发布时间】:2013-08-30 15:14:53
【问题描述】:

举个例子:

<?php

class Model
{

    private $data = [];

    public function __set($property, $value)
    {   
        $this->data[$property] = $value;
    }

    public function __get($property)
    {
        if(isset($this->data[$property]))
        {
            return $this->data[$property];
        }
        throw new Exception("Error trying to access undefined data");
    }

    public static function all()
    {
        // returns all models
    }

    public function save()
    {
        // save something to database 
    }
}

还有这个类:

class Person extends Model 
{
    protected $name;

    public static function migrateNamesToUppercase()
    {   
        foreach(self::all() as $person)
        {
            $person->name = strtoupper($person->name);
            $person->save();
        }
    }

}
  • 内部静态方法“Person::migrateNamesToUppercase”$person-&gt;name 为空。

  • 外部静态方法“Person::migrateNamesToUppercase”(new Person())-&gt;name 抛出预期异常。

当类实例存在于同一个类的静态方法中时,PHP 只是假设它可以访问受保护的属性并且__get__set 都不会被执行!可悲的是,同样的事情也发生在私有财产上。

我的问题是:实例的​​行为在两种情况下不应该相同吗?这是一个已知的错误还是只是一个失败的 PHP OO 实现?

  • 我用谷歌搜索了一下,什么也没找到

【问题讨论】:

  • 你运行的是 PHP 5.4 还是 5.5,它们是不同的版本
  • 这两个版本都会发生。我不确定 5.3
  • 所有这些static 方法都没有面向对象的东西......
  • 刚刚注意到这一点:public function $data = [];。特别是function 部分。不知道是不是这个问题。
  • 你有这个人的照片吗?考虑到她is a 模特(cough LSP cough,我真的很想见到她

标签: php oop


【解决方案1】:

__get() 用于从不可访问的属性中读取数据。

See the PHP manual for details

它按定义工作。 $name 可从对象访问,因此它不使用该方法。如果$name 是私有的并在父类中定义,它将无法访问,因此将使用该方法。

【讨论】:

  • @marcioAlmada 从根本上说,当您将静态方法放入另一个类时,您正在做出设计决策。我认为考虑到__get() 的定义[无论如何你都在以一种非常愚蠢的方式使用它],这是完全合理的行为
  • "在静态方法 "Person::migrateNamesToUppercase" $person->name 中为空。"那么为什么不呢?您专门添加了protected $name;,因此可以在类定义中的任何方法中访问它。 __get 仅对未在类中明确和公开定义的属性调用。在该类内部,私有/受保护属性是可访问的,因此不应调用 __get
  • @marcioAlmada 为什么不呢?一个类怎么能不能访问它自己的受保护属性,即使是静态方法呢?我认为 Java 也是这样工作的!
  • 事实并非如此。您在该类定义中,为什么不能设置私有/受保护的属性?
  • 只有类中的方法(静态或其他)才会有这种行为。您的错误是认为静态和非静态方法完全不同。
猜你喜欢
  • 2013-04-07
  • 2011-03-15
  • 1970-01-01
  • 1970-01-01
  • 2012-12-04
  • 2015-03-04
  • 1970-01-01
  • 2012-09-18
  • 2012-03-25
相关资源
最近更新 更多