我有这个例子由书提供:
class Address {
protected $city;
public function setCity($city) {
$this -> city = $city;
}
public function getCity() {
return $this -> city;
}
}
class Person {
protected $name;
protected $address;
public function __construct() {
$this -> address = new Address;
}
public function setName($name) {
$this -> name = $name;
}
public function getName() {
return $this -> name;
}
public function __call($method, $arguments) {
if (method_exists($this -> address, $method)) {
return call_user_func_array(
array($this -> address, $method), $arguments);
}
}
}
$rasmus=new Person;
$rasmus->setName('Rasmus Lerdorf');
$rasmus->setCity('Sunnyvale');
print $rasmus->getName().' lives in '.$rasmus->getCity().'.';
但是我对此代码有所了解。
他如何使用__construct来聚合对象以及为什么他需要__call函数?
答案 0 :(得分:3)
__construct
是Person
类的构造函数,是实例化每个Person
对象的。
__call
允许在setCity
类型的对象上调用Person
方法。类Person
不具有名为setCity
的方法,但通过使用__call
,它将该方法调用传递给类型为{{1}的$address
实例变量}。 Address
类包含Address
的实际定义。
两者都是PHP魔术功能: http://php.net/manual/en/language.oop5.magic.php
答案 1 :(得分:2)
创建新对象时人 __construct
始终执行魔术方法,该方法会将新属性$address
设置为Address
类的实例。 />
每次调用 Person 类的不存在的方法时,都会调用Magic方法__call
。 Person 类没有getCity
方法。因此,它尝试调用getCity
对象的同名方法($address
)。
此外,它还检查地址类中是否存在该方法,因此,如果您调用$rasmus->getStreet()
,则不会执行该方法,因为此处未定义getStreet
方法地址类。
答案 2 :(得分:1)
聚合对象是包含其他对象的对象。 Person类中的__construct
方法创建一个Address对象,然后将其存储为属性。
__call方法是一种所谓的“魔术方法”,每次在不存在的对象上调用方法时都会发生这种方法。在您的代码中,您正在调用$rasmus->getCity()
。 Person类中不存在此方法,因此当您尝试调用它时,它实际上会调用__call
方法。
在__call
方法中,代码试图检测Address对象中是否存在该方法 - 如果存在,则调用它。
因此,当您致电$rasmus->getName()
时,它正在调用Person->getName
方法,但当您致电$rasmus->getCity()
时,它实际上会调用Address->getCity
方法。