用了一年的Opencart,总觉得要记下点什么。一方面检验一下自己对这个开源程序的理解程度,另一方面是作个笔记,以备不时之需!
1.MVCL
MVC算是老生常谈了,opencart里多了一个语言层 L ,在目录里看起来是这样的:
opencart |--admin |--catalog |----controller |----language |----model |----view |--image |--system |--index.php
opencart是网站根目录,catalog前台,system核心文件。这样的结构目录看起来一目了然
2.注册树模式
opencart的核心架构运用的是注册树模式,registry.php
final class Registry { private $data = array(); public function get($key) { return (isset($this->data[$key]) ? $this->data[$key] : null); } public function set($key, $value) { $this->data[$key] = $value; } public function has($key) { return isset($this->data[$key]); } }
入口文件index.php 中则这样:
// Registry $registry = new Registry(); // Loader $loader = new Loader($registry); $registry->set(‘load‘, $loader);
把所有核心文件的实例都保存在Registry对象中,其结果就是Registry对象像一颗巨大的树,包含了所有控制结构的对象,然后,
在控制器中加载语言包这样的:
1 $this->load->language(‘checkout/cart‘);
加载模型是这样的:
$this->load->model(‘catalog/product‘);
接收表单参数这样的:
$this->request->post[‘quantity‘]
加载配置文件:
$this->config->get(‘config_template‘)
加载模版:
$this->load->view(‘default/template/error/not_found.tpl‘, $data)
这样的好处是我们在处理业务逻辑的时候可以以这样的方法调用任意模版、模型、配置文件、第三方类库等。虽然看起来这样加载显得冗余,且大多数时候也确实不需要这么多的类库,但是opencart的核心文件非常小巧,这样的设计我觉得还是比较高效的。
3. 前端控制器(Front Controller)、路由和输出
3.1 在控制器目录controller/common中有两个特殊的控制器类 maintenance.php和seo_url.php 每次有url请求时在入口处都是先加载这两个类,这两个类的2个作用:
a.劫取每次请求的url并重新处理,当然也可以不处理url,具体在配置文件中配置
b.类似钩子,配合接下来的路由选择分发
3.2 路由
a. front.php负责分发(dispatch),并用maintenance.php或seo_url.php去调用action.php类
b. action.php获取当前请求的url,实例化并执行
3.3 输出
a.打开缓冲区, 把当前控制器的$data变量和对应的模版全部输出,并保存在Response.php类的私有变量$output中
public function view($template, $data = array()) { $file = DIR_TEMPLATE . $template; if (file_exists($file)) { extract($data); ob_start(); require($file); $output = ob_get_contents(); ob_end_clean(); return $output; } else { trigger_error(‘Error: Could not load template ‘ . $file . ‘!‘); exit(); } }
public function setOutput($output) { $this->output = $output; }
b.入口文件最后一句,$response->output();输出