OpenCart中令人困惑的类和方法调用 [英] Confusing class and method call in OpenCart
问题描述
我有一个框架(OpenCart)Controller类(例如:catalog/controller/product/product.php),代码如下:
I have a framework (OpenCart) Controller class (like: catalog/controller/product/product.php) the code looks like:
class ControllerProductProduct extends Controller {
public function index() {
//some code
$this->response->setOutput($this->render());
//some more code
}
}
有一个类似$this->response->setOutput($this->render());
的表达式.我知道该表达式的用途,但是我对它的工作方式感到困惑.
there is an expression like $this->response->setOutput($this->render());
. I know what this expression is used for, but I am pretty confused in how it works.
$this
引用当前类,即ControllerProductProduct
,这意味着$this->response
对象必须存在于ControllerProductProduct
或其父类Controller
中.但这种情况并非如此.该对象实际上以Controller::registry->data['response']->setOutput()
的形式存在于父类Controller
的受保护属性中.所以不应该这样说:
$this
refers to current class i.e. ControllerProductProduct
, it means $this->response
object must exist in either ControllerProductProduct
or its parent class Controller
. But this is not the case. This object actually exists in a protected property of parent class Controller
as Controller::registry->data['response']->setOutput()
. So shouldn't it say like:
$this->registry->data['response']->setOutput();
而不是 $ this-> response-> setOutput();
instead of $this->response->setOutput();
我也提供了Controller
类的摘要,以便您有主意.
I am also giving a snippet of Controller
class so you can have idea.
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
}
我不知道这个表达式是如何工作的?知道这怎么可能吗?
I've no clue how this expression is working? Any idea how this is possible?
谢谢.
推荐答案
使用魔术方法 __get()
和__set()
,这很容易实现.
This is working very easily using magic methods __get()
and __set()
.
如果您试图获取无法访问的类变量(例如,未声明的类变量),则会调用魔术__get('property_name')
方法.
If You are trying to get an inaccessible class variable (e.g. that is not declared) a magic __get('property_name')
method is invoked.
因此,当您尝试检索$response
时,将调用魔术方法__get()
并返回$this->registry->get('response')
(因为没有声明$response
属性).
Thus when You are trying to retrieve $response
, a magic method __get()
is called and $this->registry->get('response')
is returned instead (as there is no $response
property declared).
是的,您可以改写$this->registry->get('response')->setOutput($this->render());
,但这没有多大用处,需要更多的写作.让PHP使用__get()
方法检索变量是可以的,尽管它不是很干净.
Yes, You could write $this->registry->get('response')->setOutput($this->render());
instead, but this would be of not much use and more writing. It is OK to let the PHP retrieve the variable using it's __get()
method, though it is not so clean.
无论如何,解决方案没有任何问题.
Anyway, there is nothing wrong with the solution.
稍微干净一点的解决方案是这样的:
a little bit cleaner solution would be this:
class Controller {
//...
function getResponse() {
return $this->registry->get('response');
}
//...
}
然后您可以在代码中调用一个具体方法,这将很清楚:
Then You could call a concrete method in Your code and it would be clear enough:
class ControllerProductProduct extends Controller {
public function index()
//...
$this->getResponse()->setOutput($this->render());
}
}
但是这意味着每个可能的属性都需要getXYZ
方法,而__get()
允许您扩展$registry
而不需要进一步的工作(在我描述的情况下,如果您要添加另一个属性添加到$register
中,您将不得不添加另一个getProperty()
方法-但这仍将是更清晰/更干净的解决方案).
But this would mean that there would be a need of getXYZ
method for each possible property while __get()
allows You to extend the $registry
with no further work needed (in the case I described if You would add another property to $register
You would have to add another getProperty()
method - but still this would be more clear/clean solution).
这篇关于OpenCart中令人困惑的类和方法调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!