Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在OpenCart中混淆类和方法调用_Php_Opencart_Magic Methods - Fatal编程技术网

Php 在OpenCart中混淆类和方法调用

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

我有一个框架(OpenCart)控制器类(如: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();
而不是 $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方法,也可以使用它,请参见: