多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內(nèi)最全I(xiàn)T社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php框架 > codeigniter > CodeIgniter(CI)框架加載流程及結(jié)構(gòu)分析

CodeIgniter(CI)框架加載流程及結(jié)構(gòu)分析

來源:程序員人生   發(fā)布時間:2014-09-29 08:00:01 閱讀次數(shù):4405次

入口文件入口文件主要完成下列工作:
1. 指定 CodeIgniter 框架所在目錄;
2. 定義 APPPATH 常量,指示應(yīng)用程序文件根目錄;
3. 載入 codeigniter/CodeIgniter.php 文件,啟動框架。

codeigniter/CodeIgniter.php 文件這個文件是 CodeIgniter 的基本文件,主要完成初始化 CodeIgniter 框架和啟動應(yīng)用程序兩項工作。

1. 實例化 CI_Benchmark,這個類用于標(biāo)記應(yīng)用程序執(zhí)行消耗的時間;
2. 載入應(yīng)用程序的配置文件 require(APPPATH.?config/config‘.EXT);
3. 實例化 CI_Config,這個類用于將數(shù)組封裝為可以操作的配置服務(wù);
4. 實例化 CI_Router,這個類用于分析 URL 請求,確定要執(zhí)行的控制器和動作;
5. 實例化 CI_Output,這個類提供輸出內(nèi)容的緩存和檢查服務(wù);
6. 通過 $OUT->_display_cache($CFG, $RTR) 嘗試輸出緩存內(nèi)容,如果成功,則結(jié)束程序運行;
7. 判斷控制器類定義文件是否存在。如果不存在則通過 show_404() 顯示錯誤信息;
8. 實例化 CI_Input,這個類提供對 $_GET、$_POST 的訪問手段,并封裝了一些過濾方法;
9. 實例化 CI_URI,這個類提供對 URL 的分析、構(gòu)造服務(wù);
10. 實例化 CI_Language,這個類提供多語言字符串映射服務(wù);
11. 載入 codeigniter/Base4.php 或者 codeigniter/Base5.php;
12. 載入 libraries/Controller.php;
13. 載入控制器類定義文件;
14. 實例化控制器類;
15. 如果控制器使用了 scaffolding 功能,則調(diào)用控制器的 _ci_scaffolding() 方法,否則調(diào)用控制器動作方法;
16. 通過 $OUT->_display(); 輸出內(nèi)容($OUT 是 CI_Output 的實例)。
CI_Benchmark 這個類很簡單,就是用 microtime() 函數(shù)記錄時間點,并提供 elapsed_time() 方法來計算兩個時間點之間消耗的時間。這個類功能不多,但是很實用。CodeIgniter 中大部分類都是這種設(shè)計思想,值得稱贊! CI_Config 這個類其實是在內(nèi)部維護(hù)了一個數(shù)組,用來記錄應(yīng)用程序的設(shè)置(類似 Windows 注冊表)。這種簡單的封裝可以強制應(yīng)用程序按照固定的規(guī)范訪問設(shè)置,同時又不將設(shè)置保存為全局變量,避免無意中遭到破壞或篡改。
CI_Router CI_Router 功能很單一。CI_Router 首先分析出應(yīng)用程序當(dāng)前使用的 URL 模式:PATHINFO 或普通模式。接下來從 URL 地址中分析出控制器名字、動作名以及參數(shù)名和參數(shù)值。分析的結(jié)果保存為 CI_Router 對象實例的成員變量。這里比較有特點的是,CI_Router 可以根據(jù)開發(fā)者在應(yīng)用程序設(shè)置里面定義的模式來分析 URL,而不是使用某種固定的模式。
CI_Output CI_Output 有兩個主要功能:獲得應(yīng)用程序執(zhí)行的所有輸出內(nèi)容和輸出緩存服務(wù)。應(yīng)用程序執(zhí)行的輸出結(jié)果都會保存為 CI_Output 的成員變量。然后根據(jù)應(yīng)用程序設(shè)置,CI_Output::_display() 方法會調(diào)用 CI_Output::_write_cache() 方法將輸出內(nèi)容緩存起來。下一次當(dāng)使用 CI_Output::_display_cache() 時如果緩存已經(jīng)建立了,并且沒有過期,則會直接輸出緩存內(nèi)容。在 CI_Output::_write_cache() 中,是根據(jù) URL 地址和 URL 參數(shù)來確定緩存 ID 的。因此即便是同一個控制器和動作,只要使用不同的 URL 參數(shù),也會緩存不同的內(nèi)容。這個類的功能很簡單,因此在許多動態(tài)頁面是無法使用的。例如用戶登錄前和登錄后,訪問同一個控制器和動作并使用相同的 URL 參數(shù),頁面內(nèi)容也有可能是不同的。這時,CI_Output 的緩存就不能使用。因為從本質(zhì)上來說,CI_Output 提供的緩存是在應(yīng)用程序之外的,所以應(yīng)用程序無法根據(jù)當(dāng)前狀態(tài)來決定是否緩存頁面。當(dāng)一個頁面被緩存后,對該頁面的訪問實際上根本就不會執(zhí)行應(yīng)用程序代 碼,而是由 CI_Output 取出緩存內(nèi)容直接就輸出了。
CI_Input CI_Input 是輸入數(shù)據(jù)過濾器,并且提供了對 $_GET、$_POST 的封裝服務(wù)。例如用 CI_Input::post() 方法來訪問 $_POST。由于多了這層封裝,CI_Input 可以在 post() 方法中對數(shù)據(jù)進(jìn)行更多的過濾。這種封裝從出發(fā)點上看,是很不錯的。但是這也會造成一些問題。例如 CI_Input 只有在調(diào)用 post() 方法時才能進(jìn)行過濾。如果應(yīng)用程序使用 $_POST 直接獲取數(shù)據(jù),那么實際上就繞過了安全屏障。如果應(yīng)用程序使用了第三方庫,那么這種風(fēng)險更大,因為第三方庫很可能會直接使用 $_POST 等全局變量。因此有些開發(fā)者認(rèn)為過濾應(yīng)該是全局的,即在框架初始化時,就對所有輸入數(shù)據(jù)進(jìn)行過濾。但初始化時的全局過濾靈活性很差,要么全過濾,要么都不 過濾,沒法做到對個別數(shù)據(jù)的單獨過濾。
CI_Input 的另一個問題,就是沒有處理 magic_quotes。不管 magic_quotes 設(shè)置為什么,CI_Input 都沒有對數(shù)據(jù)進(jìn)行相關(guān)的處理。這樣一來,如果服務(wù)器的 magic_quotes 設(shè)置不同,那么應(yīng)用程序得到的數(shù)據(jù)也是不一致的。后來查看數(shù)據(jù)庫驅(qū)動的代碼,發(fā)現(xiàn) CI_Input 將對 magic_quotes 的處理放到了數(shù)據(jù)庫驅(qū)動中。這種設(shè)計是有很大缺陷的!如果應(yīng)用程序取得數(shù)據(jù)后,并不是存入數(shù)據(jù)庫(例如直接顯示或存入文件),那么就必須自行判斷 magic_quotes 的狀態(tài)。這種判斷不但煩瑣,而且容易遺忘。所以框架有責(zé)任將所有數(shù)據(jù)整理為一致的格式,要么是應(yīng)用 addslashes() 轉(zhuǎn)義過后的數(shù)據(jù),要么是沒有轉(zhuǎn)義的數(shù)據(jù)。奇怪的是 CI_Input 卻對輸入數(shù)據(jù)的字段名進(jìn)行了 magic_quotes 檢查,并應(yīng)用了 addslashes()。這是為了讓數(shù)據(jù)庫字段名不會成為 SQL 注入攻擊的根源。甚至,CI_Input 還會將 替換為 。這種隨意篡改原始數(shù)據(jù)的做法,非常不可取。總之,我個人認(rèn)為 CodeIgniter 在這部分的設(shè)計是很糟糕的。不過要改善也很簡單,幾行代碼就可以了。然后修改一下數(shù)據(jù)庫驅(qū)動。但是由于已經(jīng)有許多采用 CodeIgniter 開發(fā)的應(yīng)用程序,所以這樣的升級改動,影響是非常大的。
CI_URI 由于 CodeIgniter 允許應(yīng)用程序定義 URL 映射模式,所以需要專門的工具來生成 URL 地址。CI_URI 就是完成這些工作的。
CI_Language 這個類可以載入不同的語言文件。然后應(yīng)用程序就可以用 CI_Language::line() 方法取出某個項目的對應(yīng)翻譯。每個語言文件就是一個名值對數(shù)組。所以 CI_Language::line() 以項目名做為鍵名,就可以查詢到對應(yīng)的翻譯。
codeigniter/Base codeigniter/Base4.php 和 codeigniter/Base5.php 功能一樣,只不過分別適用于 PHP4 和 PHP5 而已。其中定義了 CI_Base 類和一個非常重要的 get_instance() 函數(shù)。
get_instance() 函數(shù)返回一個 CI_Base 類在整個應(yīng)用程序中的唯一實例。這里有一個有趣的發(fā)現(xiàn)。Base4.php 和 Base5.php 中的 CI_Base 和 get_instance() 有這完全不同的實現(xiàn)。在 Base4.php(對應(yīng) PHP4)中,CI_Base 直接繼承自 CI_Loader。CI_Base 實例化時,將 自身的引用保存到了 CI_Base::$load 中。也就是說 CI_Base 實例的 $load 實際上指向自己。然后 $load 被復(fù)制到一個名為 $OBJ 的全局變量。在 PHP4 版的 get_instance() 函數(shù)中,如果檢查到 $CI(這是 CI_Base 的實例,也就是控制器的實例)存在,就返回 $CI,否則返回全局變量 $OBJ->load。但由于在 PHP4 中,$OBJ->load 實際上就是一個 CI_Base 的實例。所以。。。。所以。。。。。。還是返回了一個 CI_Base 的實例。真搞不懂作者為什么這樣寫,簡直要讓人發(fā)瘋。不管怎么樣,應(yīng)用程序其他地方調(diào)用 get_instance() 都會獲得一個 CI_Base 的實例。在 Base5.php(對應(yīng) PHP5)中,用一個 singleton 模式來解決了這個問題。因此 CI_Base 也不再需要從 CI_Loader 繼承了。不過這也留下了隱患(CI_Loader 實例要什么時候獲取呢?),所以在 CI_Base 的繼承類 Controller 中,只好通過判斷是否是運行 PHP5 來決定是不是要實例化一個 CI_Loader。真的很無語啊,這種設(shè)計雖然可以用,但是很糟糕。在 PHP4 種,CI_Loader 的方法和成員變量暴露在了 CI_Base 中。如果應(yīng)用程序不小心調(diào)用了這些方法或使用了這些成員變量。那么應(yīng)用程序在 PHP5 中運行就會出錯。
Controller Controller 類是所有控制器的基礎(chǔ)類。Controller 實例化時會將 CI_Input、CI_Benchmark、CI_Config、CI_URI、CI_Output、CI_Language 的實例復(fù)制到 Controller 實例的成員變量中。然后根據(jù)應(yīng)用程序設(shè)置,自動載入文件。但是這里作者顯然沒有處理好,所以不得不用 global $IN, $BM, $CFG, $URI, $LANG, $OUT; 這樣的全局變量來傳遞幾個重要的對象實例。
Controller 本身并沒提供 model、helper 的載入服務(wù)。這些都由 CI_Loader 來提供。但是,CI_Loader 的各種載入服務(wù),卻又用 get_instance() 獲取控制器的實例,然后調(diào)用 Controller(控制器都是 Controller 的繼承類哦)的 _ci_initialize()、_ci_init_database() 等方法來做初始化。神啊!我吧!這種錯綜復(fù)雜的關(guān)系,真的要人命啊! Controller 的 $ci_is_loaded 成員變量用于保存已經(jīng)載入的對象實例。所以每次用 Controller::_ci_load_model() 載入模塊后,都要將該模塊登記到 $ci_is_loaded,以避免重復(fù)載入。
Controller 里面大部分是一些初始化各種服務(wù)的方法,例如初始化數(shù)據(jù)庫、Model 的方法。還有就是用 _ci_scaffolding() 調(diào)用 CodeIgniter 的“腳手架”功能。對 Controller 的設(shè)計,沒什么好說的,一個字:爛! CI_Loader CI_Loader 提供各種載入服務(wù),例如載入 Model、Helper、View 等。但是(我真的很痛恨“但是”這個詞),CI_Loader 卻需要 Controller 來完成初始化。那么又是誰來調(diào)用 CI_Loader 呢?答案是 Controller。這種緊密的耦合,完全是沒有必要的!控制器開始執(zhí)行分析到這里,終于進(jìn)入應(yīng)用程序的代碼了。應(yīng)用程序控制器中,可以用 $this->load 來載入各種服務(wù),然后就可以調(diào)用這些載入的服務(wù)了。雖然 CodeIgniter 在 CI_Base、Controller 和 CI_Loader 上設(shè)計很糟糕,但開發(fā)者如果不在乎這些,那么開發(fā)過程還是很愉快的。下面我們再來看看 CodeIgniter 主要服務(wù)的特點。數(shù)據(jù)庫訪問與大部分框架不同,CodeIgniter 的 Model 類沒有提供數(shù)據(jù)庫訪問功能。所有數(shù)據(jù)庫操作都是通過數(shù)據(jù)庫驅(qū)動程序來進(jìn)行的。所有數(shù)據(jù)庫驅(qū)動均繼承自 CI_DB 類。等等,我怎么找不到 CI_DB 類的定義呢?因為 CI_DB 類是在 Controller 中用 eval(’class CI_DB extends CI_DB_driver { }’); 這行代碼來定義的。定義這樣一個空殼,估計是作者為以后擴(kuò)充數(shù)據(jù)庫驅(qū)動留下的伏筆。
CodeIgniter 的數(shù)據(jù)庫驅(qū)動,功能都很簡單,和 AdoDB Lite 類似,但是缺乏 AdoDB Lite 那么多的擴(kuò)展庫。我個人認(rèn)為反倒不如用 AdoDB Lite 來替換這部分。當(dāng)然了,CodeIgniter 目前已經(jīng)有不少數(shù)據(jù)庫驅(qū)動了,所以替換成 AdoDB Lite 好處不多。
CodeIgniter 也提供了一個 ActiveRecord 實現(xiàn),不過這個 ActiveRecord 可沒有一點半點的“ORM”能力。但是 CodeIgniter 的 ActiveRecord 不需要為每一個數(shù)據(jù)表都構(gòu)造一個實例。通常一個實例就可以處理多個數(shù)據(jù)表的操作。例如 $query = $this->db->get(’mytable’); 和 $query = $this->db->get(’mytable2′); 就可以分別取得 mytable 和 mytable2 的數(shù)據(jù)。說實話,作者可能用錯了名字。CodeIgniter 中的“ActiveRecord”實際上是表數(shù)據(jù)入口模式――TableDataGateway。
CodeIgniter 中的 ActiveRecord 基本上只是一個對數(shù)據(jù)表進(jìn)行 CRUD 操作的公共接口。沒有提供 RoR、CakePHP、FleaPHP 等框架具有的數(shù)據(jù)表關(guān)聯(lián)自動處理能力。和自己寫 SQL 相比,沒什么優(yōu)勢。唯一的好處就是作者所說的可以讓 ActiveRecord 來生成這些簡單的 SQL 語句,而不用自己寫,提高應(yīng)用程序在不同數(shù)據(jù)庫之間移植的能力。
“腳手架”功能 CodeIgniter 中提供了基本的“腳手架”功能,可以用幾行代碼即實現(xiàn)一個對某個數(shù)據(jù)表進(jìn)行 CRUD 的界面。這和 phpMyAdmin 中的數(shù)據(jù)瀏覽、編輯頁面類似,當(dāng)然功能要簡單得多。
“腳手架”有什么實用價值,眾說紛紜。但普遍認(rèn)同的一點就是“腳手架”功能為處于開發(fā)初期的應(yīng)用程序提供了管理數(shù)據(jù)的界面。開發(fā)者可以在后期替換掉“腳手 架”的界面。但是,CodeIgniter 也太簡單了,就只有 CRUD 操作,還不如 phpMyAdmin 好用。其他 CodeIgniter 還有許多其他的類和助手。這些類基本上都屬于提供各種輔助服務(wù)的范疇。有些類很不錯,像圖片操作。但大部分類和助手實在太簡單,缺乏實用價值。像數(shù)據(jù)驗證 助手,只能做很基本的驗證,在絕大多數(shù)應(yīng)用程序里面都不能滿足要求。總結(jié)咳――咳――,總結(jié)時間到了。再次鄭重申明:本文所有文字均為作者個人理解和感 想。作者盡量做到客觀,但人非圣賢,難免參雜個人好惡在其中。所以如果你看到不爽的文字,請自動無視,謝謝合作! CodeIgniter 是一個:簡單不簡潔、好用但可能不夠用的工具。幾個步驟就可以讓你的應(yīng)用程序跑起來,所以簡單。因為簡單,所以好用。但糟糕的設(shè)計增加了復(fù)雜度,簡單的表 面下是錯綜復(fù)雜的對象關(guān)系。因為過于簡單,所以可能不夠用。如果你只是開發(fā)很簡單的應(yīng)用程序,那么 CodeIgniter 完全可以滿足你的需求。而且你也會獲得愉快的體驗。但如果應(yīng)用程序具有一定的復(fù)雜度,CodeIgniter 就可能起到反作用。因為 CodeIgniter 在幾個主要類上的糟糕設(shè)計,你的應(yīng)用程序最終也會受到牽連。而且 CodeIgniter 缺乏許多必須的服務(wù),例如訪問控制、用戶管理、自動化的數(shù)據(jù)表關(guān)聯(lián)處理、復(fù)雜緩存等。這些服務(wù)對于一個較為復(fù)雜的應(yīng)用程序來說都是必須的。如果用 CodeIgniter 作為應(yīng)用程序框架,那么這些服務(wù)都需要自己實現(xiàn)。這時 CodeIgniter 帶來的好處就很少了。


生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 性欧美video视频另类 | 久久精品一区二区免费看 | 在线看中文字幕 | 五月天福利视频 | 宅男午夜视频在线观看 | 波多野结衣在线观看网址 | 亚洲国产日韩综合久久精品 | 成人影院久久久久久影院 | 亚洲国产高清在线精品一区 | 国产免费高清福利拍拍拍 | 在线黄视频网站 | 日本黄色大片视频 | 国产91区精品福利在线社区 | 欧美日韩视频在线播放 | 中文字幕免费高清视频 | 日本www高清免费视频观看 | 亚洲高清视频在线观看 | 国产69精品久久久久999三级 | 综合亚洲欧美日韩一区二区 | 国产日产欧产精品精品推荐在线 | 男女很舒服爽视频免费 | 国产二区三区毛片 | 狼人天堂网 | 欧美日一区二区三区 | 亚洲午夜精品久久久久久成年 | 久久色亚洲 | 中出丰满大乳中文字幕 | 国产二区三区毛片 | 亚洲综合日韩中文字幕v在线 | 天天爱综合网 | 91精品国产色综合久久不 | 日本护士xxxx视频 | 免费a级作爱片免费观看中 免费a网站 | 亚洲欧洲精品久久 | 日本一区二区三区在线 视频 | 久久亚洲影院 | 国产一区三区二区中文在线 | 亚洲a级黄色 | 最近好中文字幕国语免费高清 | 欧美巨大精品欧美一区二区 | 性一交一乱一伦 |