我通常尽量避免使用PHP的魔术方法,因为它们似乎混淆了对象的公共接口。也就是说,它们似乎越来越多地被使用,至少在我读过的代码中是这样,所以我不得不问:在什么时候使用它们有什么共识吗?使用这三种神奇方法有什么共同的模式吗?
发布于 2011-05-12 23:00:27
__call()
我见过它用于实现行为,就像通过可插拔接口向类添加额外的函数一样。
伪代码如下:
$method = function($self) {};
$events->register('object.method', $method);
$entity->method(); // $method($this);它还使得编写大多数类似的函数变得更容易,比如在ORM中。例如:
$entity->setName('foo'); // set column name to 'foo'__get()/__set()
我主要看到它被用来包装对私有变量的访问。
ORM是脑海中浮现的最好的例子:
$entity->name = 'foo'; // set column name to 'foo'发布于 2011-05-12 22:50:52
主要原因是您不需要键入那么多内容。比方说,您可以将它们用于ORM记录,并充当隐式setter/getter:
使用__call()
$user = new User();
$user->setName("Foo Bar");
$user->setAge(42);
$user->save();使用__set()
$user->name = "Foo Bar";
$user->age = 42;它映射到一个简单的数组:
array(
"name" => "Foo Bar",
"age" => 42
)将这样的数组写入数据库要比进行大量手动调用来收集所有需要的信息容易得多。与公共成员相比,__set()和__get()还有另一个优势:您可以验证/格式化数据。
发布于 2011-05-12 23:31:59
它允许你这样做:
class myclass {
private $propertybag;
public function __get($name) {
if(isset($this->propertybag[$name]) {return $this->propertybag[$name];}
throw new Exception("Unknown property " . (string) $name);
}
}然后,您可以在一行中从SQL查询填充$propertybag,而不是一个接一个地设置一大堆属性。
此外,它还允许您拥有特定的属性,这些属性是只读的(即不允许通过__set()修改)。例如,可能对ID字段有用。
此外,您还可以将代码放入__get()和__set()中,这样您就可以做一些比获取或设置单个变量更复杂的事情。例如,如果您有一个storeID字段,您可能还想提供一个storeName属性。您可以通过交叉引用查找在__get()中实现它,因此您可能不需要将名称实际存储在类中。当然,不希望在__get()中实现storeName。
有很多可能性。
当然,使用魔法方法也有一些缺点。对我来说,最大的问题是你失去了IDE中的自动完成功能。这对你可能重要,也可能无关紧要。
https://stackoverflow.com/questions/5979830
复制相似问题