在类属性中未定义变量是正常的,但在构造函数中立即指示? 我只是学习OOP,并找到了这个例子:
class Foo {
public function __construct($name) {
$this->_name = $name;
}
}
它有效,我可以使用这个变量
$objFoo = new Foo('Fido');
echo $objFoo->_name; //output 'Fido'
但是在类属性中,没有已定义的变量$ _name,如类开头的public $_name
。
所以,如果我们不直接定义它,它将通过构造函数自动创建?是否真的设置变量的范围,保护,私有?
答案 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
以及所有这些魔术方法。