opencart源码解析之 index.php
Posted neights
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencart源码解析之 index.php相关的知识,希望对你有一定的参考价值。
//访问index.php,安全过滤、加载配置文件、核心启动文件、函数库、类库 //转载请注明: http://blog.csdn.net/dabao1989/article/details/21223585 //new注册表 $registry = new Registry(); //$registry里保存的config是根据当前店店铺(`oc_store`)获取`store_id`,然后到`oc_setting`里取出该店的配置信息,跟配置文件config.php无关 $query = $db->query("SELECT * FROM " . DB_PREFIX . "setting WHERE store_id = ‘0‘ OR store_id = ‘" . (int)$config->get(‘config_store_id‘) . "‘ ORDER BY store_id ASC"); foreach ($query->rows as $setting) { if (!$setting[‘serialized‘]) { $config->set($setting[‘key‘], $setting[‘value‘]); } else { $config->set($setting[‘key‘], unserialize($setting[‘value‘])); } } //依次new核心类,压入$registry,最后几个类需要当前$registry作为参数,new之后再重新压入$registry $registry->set(‘customer‘, new Customer($registry)); //new Front();加载前置Action $controller = new Front($registry); $controller->addPreAction(new Action(‘common/seo_url‘)); $controller->addPreAction(new Action(‘common/maintenance‘)); //根据当前URL,加载指定Action,默认加载Action(‘common/home‘); if (isset($request->get[‘route‘])) { $action = new Action($request->get[‘route‘]); } else { $action = new Action(‘common/home‘); } //new Action()所进行的操作,根据URL路由,判断是否是一个控制器文件,如果是,break //保存此控制器文件路径、当前需要执行的方法、参数等,假如方法名为空则要执行的方法名保存为index function __construct($route, $args = array()) { $path = ‘‘; $parts = explode(‘/‘, str_replace(‘../‘, ‘‘, (string)$route)); foreach ($parts as $part) { $path .= $part; if (is_dir(DIR_APPLICATION . ‘controller/‘ . $path)) { $path .= ‘/‘; array_shift($parts); continue; } if (is_file(DIR_APPLICATION . ‘controller/‘ . str_replace(array(‘../‘, ‘..\\‘, ‘..‘), ‘‘, $path) . ‘.php‘)) { $this->file = DIR_APPLICATION . ‘controller/‘ . str_replace(array(‘../‘, ‘..\\‘, ‘..‘), ‘‘, $path) . ‘.php‘; $this->class = ‘Controller‘ . preg_replace(‘/[^a-zA-Z0-9]/‘, ‘‘, $path); array_shift($parts); break; } } if ($args) { $this->args = $args; } $method = array_shift($parts); if ($method) { $this->method = $method; } else { $this->method = ‘index‘;//默认index } } //Front执行控制器, 先执行之前压入的前置控制器, 然后执行当前请求的控制器, 失败则执行控制器error/not_found //前置控制器有seo_url,maintenance,后台应该可配置SEO,可能会根据SEO创建新的控制器并返回,覆盖,执行 //Front->dispatch()会调用$this->execute()执行控制器 //execute()内部通过调用is_callable()判断控制器方法是否可以调用,所以可以在子Controller中将index()定义为protected,防止直接调用 //当直接调用时child Controller中的protected方法时,将会转到error/not_found $controller->dispatch($action, new Action(‘error/not_found‘)); function dispatch($action, $error) { $this->error = $error; foreach ($this->pre_action as $pre_action) { $result = $this->execute($pre_action); if ($result) { $action = $result;//重置 break; } } while ($action) { $action = $this->execute($action); } } function execute($action) { if (file_exists($action->getFile())) { require_once($action->getFile()); $class = $action->getClass(); $controller = new $class($this->registry); if (is_callable(array($controller, $action->getMethod()))) { $action = call_user_func_array(array($controller, $action->getMethod()), $action->getArgs()); } else { $action = $this->error;//当不可用时,会调用$this->error $this->error = ‘‘; } } else { $action = $this->error; $this->error = ‘‘; } return $action; } //假设执行的控制器是common/home, 没有指定方法, 则执行index() class ControllerCommonHome extends Controller { public function index() { $this->document->setTitle($this->config->get(‘config_title‘)); $this->document->setDescription($this->config->get(‘config_meta_description‘)); $this->data[‘heading_title‘] = $this->config->get(‘config_title‘); if (file_exists(DIR_TEMPLATE . $this->config->get(‘config_template‘) . ‘/template/common/home.tpl‘)) { $this->template = $this->config->get(‘config_template‘) . ‘/template/common/home.tpl‘; } else { $this->template = ‘default/template/common/home.tpl‘; } $this->children = array( ‘common/column_left‘, ‘common/column_right‘, ‘common/content_top‘, ‘common/content_bottom‘, ‘common/footer‘, ‘common/header‘ ); $this->response->setOutput($this->render()); } } //Controller中的render()方法 //会判断children属性是否赋值,有的话会逐个new child Controller,child Controller仍可以$this->render(),但调用$this->render()必须设定$this->template //$this->data数组存储的值可在模板中使用 //$this->data[basename[$child]]保存的是子模板,common/home.tpl可以通过调用echo $column_left、$column_right、$content_top、$content_bottom输出 //应注意$this->data数组中的键值不要和子模板名重复! function render() { foreach ($this->children as $child) { $this->data[basename($child)] = $this->getChild($child); } if (file_exists(DIR_TEMPLATE . $this->template)) { extract($this->data);//模板中使用 ob_start(); require(DIR_TEMPLATE . $this->template); $this->output = ob_get_contents(); ob_end_clean(); return $this->output; } else { trigger_error(‘Error: Could not load template ‘ . DIR_TEMPLATE . $this->template . ‘!‘); exit(); } } //controller中的getChild()方法 //只有在child Controller中执行了$this->render(),父Controller在$this->data[basename($child)]才能捕获到子模板,否则捕获的是空字符串 //虽然child Controller中的index()被定义为protected, 但是可以被父Controller调用, 因为他们都继承自Controller function getChild($child, $args = array()) { $action = new Action($child, $args); if (file_exists($action->getFile())) { require_once($action->getFile()); $class = $action->getClass(); $controller = new $class($this->registry); $controller->{$action->getMethod()}($action->getArgs()); return $controller->output; } else { trigger_error(‘Error: Could not load controller ‘ . $child . ‘!‘); exit(); } } //在主Controlle中,this->render()返回的模板需要传送给$this->response->setOutput()才能输出 $this->response->setOutput($this->render()); //Controller中的语言包使用,$this->language保存在$registry中 $this->language->load(‘common/footer‘); $this->data[‘text_information‘] = $this->language->get(‘text_information‘); $this->data[‘text_service‘] = $this->language->get(‘text_service‘); //Controller中session使用,$this->session保存在$registry中 $this->session->data[$key]; $this->session->data[$key] = ‘hello‘; //Controller中的$this->request数组 $this->get = $_GET; $this->post = $_POST; $this->request = $_REQUEST; $this->cookie = $_COOKIE; $this->files = $_FILES; $this->server = $_SERVER; $this->request->get[‘route‘];//获取方式 //Controller中的$this->response使用 $this->response->setOutput($this->render()); $this->response->setOutput(json_encode($json)); $this->response->addHeader(‘Content-Type: application/xml‘); //Controller中的$this->customer $this->customer->isLogged();//判断登录状态 $this->customer->logout();//退出操作 $this->customer->login();//登录操作 $this->getId();//获取用户ID,存储在customer表中的customer_id //Controller中的页面跳转,$url->link()用于生成控制器的链接,如下 $this->redirect($this->url->link(‘catalog/information‘, ‘token=‘ . $this->session->data[‘token‘] . $url, ‘SSL‘)); //Controller中的forward(),用于new 新的控制器,并返回 function forward($route, $args = array()) { return new Action($route, $args); } //Controller中的模型加载 $this->load->model(‘catalog/category‘); $this->model_catalog_category;//使用格式 //cache使用(原始使用文件缓存) $this->cache->get($key); $this->cache->set($key, $value); $this->cache->delete($key); //js,css等静态文件加载,通过Document对象加载额外的JS,CSS链接,在common子模板中会自动输出 $registry->document; $registry->document->addLink($href, $rel); $registry->addStyle($href, $rel = ‘stylesheet‘, $media = ‘screen‘); $registry->addScript($script); //币种 //模型机制 //在index.php创建数据库连接,并保存在$registry,根据DB_DRIVER不同,调用system/database/下指定的数据库引擎 //拥有4个方法:query(),escape(),countAffected(),getLastId() //当验证外部数据时要用escape()进行安全过滤 $db = new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE); $registry->set(‘db‘, $db); //数据表解析 //oc_setting 配置 //oc_url_alias 配合apache rewrite,进行商品及分类URL优化
以上是关于opencart源码解析之 index.php的主要内容,如果未能解决你的问题,请参考以下文章