在类属性中不定义变量,但在构造函数中立即表示变量是正常的吗?我只是学习了OOP,并发现了这个例子:
class Foo {
public function __construct($name) {
$this->_name = $name;
}
}
它起作用,我可以使用这个变量
$objFoo = new Foo('Fido');
echo $objFoo->_name; //output 'Fido'
但是在类属性中,没有定义变量$_name,比如类开始时的public $_name
。因此,如果我们不直接定义它,它将自动创建通过构造函数?用这种方式为变量设置范围是真的吗,受保护的,私有的?
发布于 2014-09-08 00:24:29
在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
和所有这些神奇的方法,原因也差不多一样。
发布于 2014-09-08 00:22:14
动态创建对象成员意味着只为其赋值而不声明成员,而不限于构造函数方法。它可以从类中的每个方法的内部完成,甚至可以从类的外部执行,如下所示:
$c = new stdClass();
$c->foo = "bar";
虽然对此仍然有一些用例,但我建议在类的前面显式地声明每个类成员。而且,在大多数情况下,您希望将类成员声明为protected
,甚至private
,这无论如何都需要显式声明。
https://stackoverflow.com/questions/25719960
复制