我有一个框架(OpenCart)Controller类(如:catalog / controller / product / product.php)代码如下:
class ControllerProductProduct extends Controller {
public function index() {
//some code
$this->response->setOutput($this->render());
//some more code
}
}
有一个像$this->response->setOutput($this->render());
这样的表达式。我知道这个表达式用于什么,但我对它的工作方式感到困惑。
$this
引用当前类,即ControllerProductProduct
,这意味着$this->response
对象必须存在于ControllerProductProduct
或其父类Controller
中。但这种情况并非如此。此对象实际上存在于父类Controller
的受保护属性中Controller::registry->data['response']->setOutput()
。所以不应该这样说:
$this->registry->data['response']->setOutput();
而不是
$这 - >响应 - > setOutput();
我还提供了Controller
课程的片段,以便您有所了解。
abstract class Controller {
protected $registry;
//Other Properties
public function __construct($registry) {
$this->registry = $registry;
}
public function __get($key) {
//get() returns registry->data[$key];
return $this->registry->get($key);
}
public function __set($key, $value) {
$this->registry->set($key, $value);
}
//Other methods
}
我不知道这个表达式是如何工作的?知道这是怎么可能的吗?
感谢。
答案 0 :(得分:1)
使用魔术方法 __get()
和__set()
非常容易。
如果您试图获取一个无法访问的类变量(例如,未声明),则会调用一个神奇的__get('property_name')
方法。
因此,当您尝试检索$response
时,会调用魔术方法__get()
并返回$this->registry->get('response')
(因为没有声明$response
属性)。< / p>
是的,您可以改为编写$this->registry->get('response')->setOutput($this->render());
,但这不会有太多用处和更多写作。让PHP使用它的__get()
方法检索变量是可以的,尽管它不是那么干净。
无论如何,解决方案没有任何问题。
编辑:一点点清洁解决方案就是这样:class Controller {
//...
function getResponse() {
return $this->registry->get('response');
}
//...
}
然后你可以在你的代码中调用一个具体的方法,它就足够清楚了:
class ControllerProductProduct extends Controller {
public function index()
//...
$this->getResponse()->setOutput($this->render());
}
}
但这意味着每个可能的属性都需要getXYZ
方法,而__get()
允许您扩展$registry
而无需进一步的工作(在我的情况下)描述你是否要向$register
添加另一个属性你必须添加另一个getProperty()
方法 - 但这仍然是更清晰/干净的解决方案。)
答案 1 :(得分:0)
这种魔法称为“超载” 这是一个较小的演示:
<?php
class PropsDemo
{
private $registry = array();
public function __set($key, $value) {
$this->registry[$key] = $value;
}
public function __get($key) {
return $this->registry[$key];
}
}
$pd = new PropsDemo;
$pd->a = 1;
echo $pd->a;
看看http://php.net/manual/en/language.oop5.overloading.php。它解释得很清楚。