Php 在OpenCart中混淆类和方法调用
我有一个框架(OpenCart)控制器类(如:catalog/Controller/product/product.php),代码如下:Php 在OpenCart中混淆类和方法调用,php,opencart,magic-methods,Php,Opencart,Magic Methods,我有一个框架(OpenCart)控制器类(如:catalog/Controller/product/product.php),代码如下: class ControllerProductProduct extends Controller { public function index() { //some code $this->response->setOutput($this->render()); //some more cod
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();
而不是
$this->response->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
}
我不知道这个表达式是怎么工作的?你知道这怎么可能吗
谢谢。这个魔法叫做“过载”。
这是一个较小的演示:
<?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;
使用神奇的方法\uuu get()
和\uu set()
可以非常轻松地工作
如果您试图获取一个不可访问的类变量(例如,未声明的类变量),则会调用magic\uu get('property\u name')
方法
因此,当您试图检索$response
时,将调用一个神奇的方法\uu get()
,并返回$this->registry->get('response')
(因为没有声明$response
属性)
是的,您可以编写$this->registry->get('response')->setOutput($this->render())代码>相反,但这不会有多大用处,也不会有更多的编写。让PHP使用它的\uu get()
方法检索变量是可以的,尽管它不是那么干净
无论如何,这个解决方案没有错
编辑:稍微干净一点的解决方案是:
class Controller {
//...
function getResponse() {
return $this->registry->get('response');
}
//...
}
然后,您可以在代码中调用一个具体的方法,这将非常清楚:
class ControllerProductProduct extends Controller {
public function index()
//...
$this->getResponse()->setOutput($this->render());
}
}
但这意味着每个可能的属性都需要getXYZ
方法,而\uu get()
允许您扩展$registry
,而无需进一步的工作(在我描述的情况下,如果您要向$register
添加另一个属性,则必须添加另一个getProperty()
方法-但这仍然是更清晰/干净的解决方案)。我有点类似的问题,只是没有声明任何get方法,也可以使用它,请参见: