【问题标题】:Why does a PHP object accept members that were only mentioned when called?为什么 PHP 对象接受仅在调用时提及的成员?
【发布时间】:2014-08-05 07:03:46
【问题描述】:

下面的代码 sn-p 我陷入了悖论,我不知道该怎么称呼它。

我已经定义了一个非常简单的类,它还没有变量。现在,在构造函数中,我接受一个键和值数组,并像这样使用 foreach 循环动态分配变量:

class Food{

    function Food($construct){
        foreach($construct as $key=>$value){
            $this->$key = $value;
        }

    }


}

如果我现在使用这样的输入创建一个实例:

$food = new Food(array('name' => 'chicken' , 'unit' => 'kg' , 'calorie' => 10000));

我会得到:

var_dump($food);    
object(Food)[1]
  public 'name' => string 'chicken' (length=7)
  public 'unit' => string 'kg' (length=2)
  public 'calorie' => int 10000

这怎么可能?

【问题讨论】:

    标签: php oop


    【解决方案1】:

    这在 PHP 中是可能的,并且是默认实现,除非您另有说明(通过 __get() 和 __set())。动态创建公共成员仅适用于当前实例,它不会为整个类创建它。并且可以从类内部或外部(例如通过实例)。

    $food->smth = 100;
    

    将创建public smth

    一个空的__set()魔术方法可以防止这种行为

    public function __set($name, $value) { }
    

    第二个问题:

    这是不安全的,使用公共成员也不安全(除非您有充分的理由公开您的属性)。约定说您必须拥有大多数私有/受保护的成员以及他们的访问器。所以你可以从类内部而不是从它的实例中控制类。还有很多其他原因,包括代码的可重用性。

    【讨论】:

    • 这很奇怪,但找不到任何有关为任何对象动态定义新属性的可能性的文档。
    • @sectus 我也没有:p
    • @sectus 它是整个语言中动态变量定义的结果。它没有记录在 OOP 部分,因为它不一定与它相关,但它记录在变量部分 php.net/manual/en/language.variables.basics.php It is not necessary to initialize variables in PHP however it is a very good practice.
    • 对象和过程式风格之间的细微差别在于过程式编程没有多个上下文。为一页中的变量赋值会为整个页面定义变量。 (不包括函数,但可以通过全局访问)
    • @RoyalBg ,所以 $object->var 没有什么可以被视为简单变量。
    【解决方案2】:

    那个变量不是未初始化的,它只是未声明。

    在类定义中声明变量是一种可读性风格。此外,您还可以设置可访问性(私有或公共)。

    无论如何,显式声明变量与 OOP 无关,它是特定于编程语言的。在 Java 中你不能这样做,因为变量必须显式声明。

    参考 - http://stackoverflow.com/questions/1086494/when-should-i-declare-variables-in-a-php-class

    【讨论】:

      猜你喜欢
      • 2011-02-05
      • 2010-12-11
      • 2014-06-14
      • 1970-01-01
      • 2012-05-04
      • 2023-04-08
      • 2020-02-28
      • 2021-02-03
      • 2017-01-23
      相关资源
      最近更新 更多