是否所有类实例都正式支持动态属性?

时间:2016-07-26 13:28:44

标签: php

令我惊讶的是,我发现,我可以在PHP中做这样的事情:

class Customer
{
    public $name;
}

$customer = new $customer;

// No error:
$customer->email = 'test@example.com';

现在我想知道:这是一个有效的PHP功能吗?我已经检查过PHP手册,但实际上无法在任何地方找到它。

背景

我正在为复杂的SOAP服务编写客户端,并将使用classmap中的SoapClient选项将一些SOAP类映射到本地PHP类。我只针对特定的SOAP类执行此操作,因为我需要向这些类添加一些相关的代码。

如果我可以避免必须定义所有SOAP属性,它将使我的PHP类更轻量级,更容易维护,因为一些SOAP服务数据类型会经常更新。

更新

为了更清楚地说明这一点:我知道这不是最好的做法,而且我知道风险。问题是如何编写好的代码或者这是否是一个好主意。

问题是:

  • 这是PHP中官方支持的功能吗?
  • 虽然现在可以使用,但是它还适用于PHP 7.x,7.1.x等吗?
  • 这在哪里记录?

基本上,它的行为就好像每个类中都有__get()__set()的内部默认实现:

private $_props = [];
public function __set($name, $value)
{
    $this->_props[$name] = $value;
}
public function __get($name)
{
    if(!isset($this->_props[$name])) {
        trigger_error('Undefined property 'get_class().'::$'.$name);
    } else {
        return $this->_props[$name];
    }
}

2 个答案:

答案 0 :(得分:4)

设置/获取未定义的属性在PHP中并不罕见,通常与StdClass http://php.net/manual/en/language.types.object.php#language.types.object.casting一起使用。例如,您将获得一个带有json_decode()的StdClass对象,这是一个本机PHP函数,因此它是完全有效的。在你的情况下使用它很好,因为你只是将数据传递给SOAP,数据本身没有由你的应用程序定义,而是由SOAP调用(wsdl?)

在其他情况下,我总是建议定义类中的所有属性,而不是使用随机未定义的属性。这样,不仅您的代码更清晰,而且您的IDE也可以更好地识别潜在的错误。

答案 1 :(得分:1)

这是完全正常的PHP。声明这样的公共属性可以帮助防止在执行if($this->name)之类的事情时设置未定义的var通知或设置默认值,但这不是必需的。