在__construct()中设置PHP变量

时间:2014-09-08 08:19:39

标签: php oop variables constructor

在类属性中未定义变量是正常的,但在构造函数中立即指示? 我只是学习OOP,并找到了这个例子:

class Foo {
  public function __construct($name) {
    $this->_name = $name;
  }
}

它有效,我可以使用这个变量

$objFoo = new Foo('Fido');
echo $objFoo->_name; //output 'Fido'

但是在类属性中,没有已定义的变量$ _name,如类开头的public $_name。 所以,如果我们不直接定义它,它将通过构造函数自动创建?是否真的设置变量的范围,保护,私有?

2 个答案:

答案 0 :(得分:1)

动态创建对象成员 ,意味着只是在不声明成员的情况下为其分配值,不仅限于构造函数方法。它可以从类中的每个方法内部甚至从类外部完成,如下所示:

$c = new stdClass();
$c->foo = "bar";

虽然还有一些用例,但我建议在类的头部明确声明每个类成员。在大多数情况下,您还希望将类成员声明为protected或甚至private,无论如何都需要明确声明。

答案 1 :(得分:1)

在PHP中,这称为"对象重载" ,您可以动态地(几乎)在任何实例上添加/设置新属性。但是,你不应该这样做。这些属性使您的代码更容易出错,可维护性更低,并且 更慢的重载属性:details here

预先声明属性可以提供更好的文档,IDE的自动完成功能实际上是值得然后,你不会养成依赖某些东西的习惯这并不总是奏效。我倾向于按照这些方式编写我的数据模型:

class DataModel
{
    /**
     * @var int
     */
    protected $id = null;

    /**
     * @var string
     */
    protected $name = null;

    /**
     * @var \DateTime
     */
    protected $birthday = null;

    public function __construct(array $data)
    {}//set values
    public function __set($name, $value)
    {
        throw new \BadMethodCallException('Do not attempt overloading, use getters and setter');
    }
}

我为所有属性定义了getter和setter,以确保类型安全,并且可以进行验证。我明确禁用了重载,因为存在拼写错误的风险,以及调试困难。我经常发现自己因为同样的原因而禁用__sleep__serialize以及所有这些魔术方法。