opencart 源碼解析

原文轉(zhuǎn)載:https://blog.csdn.net/dabao1989/article/details/21223585

//訪問index.php,安全過濾诉字、加載配置文件、核心啟動(dòng)文件、函數(shù)庫、類庫
//new注冊(cè)表
$registry = new Registry();
 
//$registry里保存的config是根據(jù)當(dāng)前店店鋪(`oc_store`)獲取`store_id`,然后到`oc_setting`里取出該店的配置信息墩朦,跟配置文件config.php無關(guān)
$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,最后幾個(gè)類需要當(dāng)前$registry作為參數(shù),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'));
    
//根據(jù)當(dāng)前URL,加載指定Action,默認(rèn)加載Action('common/home');
if (isset($request->get['route'])) {
    $action = new Action($request->get['route']);
} else {
    $action = new Action('common/home');
}
 
//new Action()所進(jìn)行的操作,根據(jù)URL路由,判斷是否是一個(gè)控制器文件匿又,如果是,break
//保存此控制器文件路徑建蹄、當(dāng)前需要執(zhí)行的方法碌更、參數(shù)等,假如方法名為空則要執(zhí)行的方法名保存為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';//默認(rèn)index
        }
}
 
//Front執(zhí)行控制器, 先執(zhí)行之前壓入的前置控制器洞慎, 然后執(zhí)行當(dāng)前請(qǐng)求的控制器痛单, 失敗則執(zhí)行控制器error/not_found
//前置控制器有seo_url,maintenance,后臺(tái)應(yīng)該可配置SEO劲腿,可能會(huì)根據(jù)SEO創(chuàng)建新的控制器并返回旭绒,覆蓋,執(zhí)行
//Front->dispatch()會(huì)調(diào)用$this->execute()執(zhí)行控制器
//execute()內(nèi)部通過調(diào)用is_callable()判斷控制器方法是否可以調(diào)用焦人,所以可以在子Controller中將index()定義為protected挥吵,防止直接調(diào)用
//當(dāng)直接調(diào)用時(shí)child Controller中的protected方法時(shí),將會(huì)轉(zhuǎn)到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;//當(dāng)不可用時(shí)花椭,會(huì)調(diào)用$this->error
 
                        $this->error = '';
                }
        } else {
                $action = $this->error;
 
                $this->error = '';
        }
 
        return $action;
}
 
//假設(shè)執(zhí)行的控制器是common/home, 沒有指定方法忽匈, 則執(zhí)行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()方法
//會(huì)判斷children屬性是否賦值,有的話會(huì)逐個(gè)new child Controller,child Controller仍可以$this->render(),但調(diào)用$this->render()必須設(shè)定$this->template
//$this->data數(shù)組存儲(chǔ)的值可在模板中使用
//$this->data[basename[$child]]保存的是子模板矿辽,common/home.tpl可以通過調(diào)用echo $column_left丹允、$column_right郭厌、$content_top、$content_bottom輸出
//應(yīng)注意$this->data數(shù)組中的鍵值不要和子模板名重復(fù)雕蔽!
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中執(zhí)行了$this->render(),父Controller在$this->data[basename($child)]才能捕獲到子模板折柠,否則捕獲的是空字符串
//雖然child Controller中的index()被定義為protected, 但是可以被父Controller調(diào)用, 因?yàn)樗麄兌祭^承自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數(shù)組
$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();//判斷登錄狀態(tài)
$this->customer->logout();//退出操作
$this->customer->login();//登錄操作
$this->getId();//獲取用戶ID,存儲(chǔ)在customer表中的customer_id
 
//Controller中的頁面跳轉(zhuǎn),$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等靜態(tài)文件加載,通過Document對(duì)象加載額外的JS,CSS鏈接,在common子模板中會(huì)自動(dòng)輸出
$registry->document;
$registry->document->addLink($href, $rel);
$registry->addStyle($href, $rel = 'stylesheet', $media = 'screen');
$registry->addScript($script);
 
//幣種
 
 
//模型機(jī)制
//在index.php創(chuàng)建數(shù)據(jù)庫連接,并保存在$registry,根據(jù)DB_DRIVER不同液走,調(diào)用system/database/下指定的數(shù)據(jù)庫引擎
//擁有4個(gè)方法:query(),escape(),countAffected(),getLastId()
//當(dāng)驗(yàn)證外部數(shù)據(jù)時(shí)要用escape()進(jìn)行安全過濾
$db = new DB(DB_DRIVER, DB_HOSTNAME, DB_USERNAME, DB_PASSWORD, DB_DATABASE);
$registry->set('db', $db);
 
//數(shù)據(jù)表解析
//oc_setting 配置
//oc_url_alias 配合apache rewrite,進(jìn)行商品及分類URL優(yōu)化
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末贾陷,一起剝皮案震驚了整個(gè)濱河市缘眶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌髓废,老刑警劉巖巷懈,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異慌洪,居然都是意外死亡顶燕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門冈爹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涌攻,“玉大人,你說我怎么就攤上這事频伤】一眩” “怎么了?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵憋肖,是天一觀的道長因痛。 經(jīng)常有香客問我,道長岸更,這世上最難降的妖魔是什么鸵膏? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮怎炊,結(jié)果婚禮上谭企,老公的妹妹穿的比我還像新娘。我一直安慰自己评肆,他們只是感情好债查,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著糟港,像睡著了一般。 火紅的嫁衣襯著肌膚如雪院仿。 梳的紋絲不亂的頭發(fā)上秸抚,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天速和,我揣著相機(jī)與錄音,去河邊找鬼剥汤。 笑死颠放,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吭敢。 我是一名探鬼主播碰凶,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼鹿驼!你這毒婦竟也來了欲低?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤畜晰,失蹤者是張志新(化名)和其女友劉穎砾莱,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凄鼻,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡腊瑟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了块蚌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闰非。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖峭范,靈堂內(nèi)的尸體忽然破棺而出财松,到底是詐尸還是另有隱情,我是刑警寧澤虎敦,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布游岳,位于F島的核電站,受9級(jí)特大地震影響其徙,放射性物質(zhì)發(fā)生泄漏胚迫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一唾那、第九天 我趴在偏房一處隱蔽的房頂上張望访锻。 院中可真熱鬧,春花似錦闹获、人聲如沸期犬。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽龟虎。三九已至,卻和暖如春沙庐,著一層夾襖步出監(jiān)牢的瞬間鲤妥,已是汗流浹背佳吞。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留棉安,地道東北人底扳。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像贡耽,于是被迫代替她去往敵國和親衷模。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355