工作原理:PHP中的Magic Methods,通过逻辑而非定义来理解它们

时间:2015-03-18 07:35:25

标签: php opencart

大家好日子! 我有以下示例(来自Opencart):

home.php:

<?php
class ControllerCommonHome extends Controller {
    public function index() {
        $this->document->setTitle($this->config->get('config_meta_title'));
        $this->document->setDescription($this->config->get('config_meta_description'));
        $this->document->setKeywords($this->config->get('config_meta_keyword'));

        if (isset($this->request->get['route'])) {
            $this->document->addLink(HTTP_SERVER, 'canonical');
        }

        $data['column_left'] = $this->load->controller('common/column_left');
        $data['column_right'] = $this->load->controller('common/column_right');
        $data['content_top'] = $this->load->controller('common/content_top');
        $data['content_bottom'] = $this->load->controller('common/content_bottom');
        $data['footer'] = $this->load->controller('common/footer');
        $data['header'] = $this->load->controller('common/header');

        if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/common/home.tpl')) {
            $this->response->setOutput($this->load->view($this->config->get('config_template') . '/template/common/home.tpl', $data));
        } else {
            $this->response->setOutput($this->load->view('default/template/common/home.tpl', $data));
        }
    }
}

Controller.php这样:

<?php
abstract class Controller {
    protected $registry;

    public function __construct($registry) {
        $this->registry = $registry;
    }

    public function __get($key) {
        return $this->registry->get($key);
    }

    public function __set($key, $value) {
        $this->registry->set($key, $value);
    }
}

我无法通过逻辑过程来了解其工作原理:

  1. “document”和setTitle(...)在哪里? $这 - &GT;文档 - &GT;的setTitle($这 - &GT; config-&GT;获得( 'config_meta_title'));

  2. “config”和get(...)在哪里? $这 - &GT;文档 - &GT; setDescription($这 - &GT; config-&GT;获得( 'config_meta_description'));

  3. 这是如何工作的?我无法看到/想到这个过程...... 我可以阅读它,但在尝试重做它时有空白。

2 个答案:

答案 0 :(得分:1)

加载或设置属性时会调用

__set__get

$this->property = 'value'; // calls __set
echo $this->property; // calls __get. 

您的get()请求由__call

处理
$this->get('foo'); // calls __call
Object::get('foo'); // calls __callStatic

请参阅有关魔术方法的文档:http://php.net/manual/en/language.oop5.overloading.php#object.call

同样在您的控制器示例中,任何__get或__set都会重定向到注册表类方法getset

因此,如果在您的示例中,$ this是一个扩展抽象类Controller的类:

$this->title = 'foo'; // redirected to registry set
echo $this->title; // redirected to registry get

根据您发布的代码,您很难确定哪些文档。然而,文档是通过注册表获取的。所以:

// request
$this->document->setTitle('foo');
// calls magic method __get
// calls $this->registry->get('document');
// returns the value in registry for document, which might be an object; let's hope so
// now run the method setTitle('foo') on the object returned from the registry

答案 1 :(得分:0)

当您引用不存在的对象的属性/属性时,实际上会调用PHP __get和__set魔术方法。然后,您可以使用属性/属性名称作为键(将其作为参数传递给这些函数)返回您想要的任何内容。在上面的例子中,它基于密钥(作为属性/属性名称)从注册表返回一个对象。

要查找源“文档”对象,您首先需要了解它在注册表中的注册方式。这很可能发生在应用程序引导过程中。我不熟悉OpenCart,但会在注册表中注册项目。一旦发现您将能够看到实例化哪种对象并将其存储到该注册表中。