codeIgniter框架基本結構 (二)

2021-08-31 05:56:57 字數 3744 閱讀 4048

[color=blue][b][size=medium]codeigniter/base[/size][/b][/color]

[color=red]codeigniter/base4.php[/color] 和 [color=red]codeigniter/base5.php [/color]功能一樣,只不過分別適用於 php4 和 php5 而已。其中定義了 ci_base 類和乙個非常重要的 get_instance() 函式。

get_instance() 函式返回乙個 ci_base 類在整個應用程式中的唯一例項。

這裡有乙個有趣的發現。base4.php 和 base5.php 中的 ci_base 和 get_instance() 有這完全不同的實現。

在 base4.php(對應 php4)中,ci_base 直接繼承自 ci_loader。ci_base 例項化時,將 自身的引用儲存到了 ci_base::$load 中。也就是說 ci_base 例項的 $load 實際上指向自己。然後 $load 被複製到乙個名為 $obj 的全域性變數。

在 php4 版的 get_instance() 函式中,如果檢查到 $ci(這是 ci_base 的例項,也就是控制器的例項)存在,就返回 $ci,否則返回全域性變數 $obj->load。但由於在 php4 中,$obj->load 實際上就是乙個 ci_base 的例項。所以。。。。所以。。。。。。還是返回了乙個 ci_base 的例項。真搞不懂作者為什麼這樣寫,簡直要讓人發瘋。

不管怎麼樣,應用程式其他地方呼叫 get_instance() 都會獲得乙個 ci_base 的例項。

在 base5.php(對應 php5)中,用乙個 singleton 模式來解決了這個問題。因此 ci_base 也不再需要從 ci_loader 繼承了。不過這也留下了隱患(ci_loader 例項要什麼時候獲取呢?),所以在 ci_base 的繼承類 controller 中,只好通過判斷是否是執行 php5 來決定是不是要例項化乙個 ci_loader。

真的很無語啊,這種設計雖然可以用,但是很糟糕。在 php4 種,ci_loader 的方法和成員變數暴露在了 ci_base 中。如果應用程式不小心呼叫了這些方法或使用了這些成員變數。那麼應用程式在 php5 中執行就會出錯。

[size=medium][color=blue][b]controller[/b][/color][/size]

controller 類是所有控制器的基礎類。

controller 例項化時會將 ci_input、ci_benchmark、ci_config、ci_uri、ci_output、ci_language 的例項複製到 controller 例項的成員變數中。然後根據應用程式設定,自動載入檔案。

但是這裡作者顯然沒有處理好,所以不得不用 `global $in, $bm, $cfg, $uri, $lang, $out;` 這樣的全域性變數來傳遞幾個重要的物件例項。

controller 本身並沒提供 model、helper 的載入服務。這些都由 ci_loader 來提供。但是,ci_loader 的各種載入服務,卻又用 get_instance() 獲取控制器的例項,然後呼叫 controller(控制器都是 controller 的繼承類哦)的 _ci_initialize()、_ci_init_database() 等方法來做初始化。

神啊!救救我吧!這種錯綜複雜的關係,真的要人命啊!

controller 的 $ci_is_loaded 成員變數用於儲存已經載入的物件例項。所以每次用 controller::_ci_load_model() 載入模組後,都要將該模組登記到 $ci_is_loaded,以避免重複載入。

controller 裡面大部分是一些初始化各種服務的方法,例如初始化資料庫、model 的方法。還有就是用 _ci_scaffolding() 呼叫 codeigniter 的「腳手架」功能。

對 controller 的設計,沒什麼好說的,乙個字:爛!

[size=medium][color=blue][b]ci_loader[/b][/color][/size]

ci_loader 提供各種載入服務,例如載入 model、helper、view 等。但是(我真的很痛恨「但是」這個詞),ci_loader 卻需要 controller 來完成初始化。那麼又是誰來呼叫 ci_loader 呢?答案是 controller。

這種緊密的耦合,完全是沒有必要的!

控制器開始執行

分析到這裡,終於進入應用程式的**了。應用程式控制器中,可以用 $this->load 來載入各種服務,然後就可以呼叫這些載入的服務了。

雖然 codeigniter 在 ci_base、controller 和 ci_loader 上設計很糟糕,但開發者如果不在乎這些,那麼開發過程還是很愉快的。

下面我們再來看看 codeigniter 主要服務的特點。

資料庫訪問

與大部分框架不同,codeigniter 的 model 類沒有提供資料庫訪問功能。所有資料庫操作都是通過資料庫驅動程式來進行的。

所有資料庫驅動均繼承自 ci_db 類。等等,我怎麼找不到 ci_db 類的定義呢?因為 ci_db 類是在 controller 中用 `eval(『class ci_db extends ci_db_driver 』);` 這行**來定義的。定義這樣乙個空殼,估計是作者為以後擴充資料庫驅動留下的伏筆。

codeigniter 的資料庫驅動,功能都很簡單,和 adodb lite 類似,但是缺乏 adodb lite 那麼多的擴充套件庫。我個人認為反倒不如用 adodb lite 來替換這部分。當然了,codeigniter 目前已經有不少資料庫驅動了,所以替換成 adodb lite 好處不多。

codeigniter 也提供了乙個 activerecord 實現,不過這個 activerecord 可沒有一點半點的「orm」能力。但是 codeigniter 的 activerecord 不需要為每乙個資料表都構造乙個例項。通常乙個例項就可以處理多個資料表的操作。

例如 `$query = $this->db->get(『mytable』);` 和 `$query = $this->db->get(『mytable2′);` 就可以分別取得 mytable 和 mytable2 的資料。

說實話,作者可能用錯了名字。

codeigniter 中的「activerecord」實際上是表資料入口模式——tabledatagateway。

codeigniter 中的 activerecord 基本上只是乙個對資料表進行 crud 操作的公共介面。沒有提供 ror、cakephp、fleaphp 等框架具有的資料表關聯自動處理能力。和自己寫 sql 相比,沒什麼優勢。唯一的好處就是作者所說的可以讓 activerecord 來生成這些簡單的 sql 語句,而不用自己寫,提高應用程式在不同資料庫之間移植的能力。

[size=medium][color=blue][b]「腳手架」功能[/b][/color][/size]

codeigniter 中提供了基本的「腳手架」功能,可以用幾行**即實現乙個對某個資料表進行 crud 的介面。這和 phpmyadmin 中的資料瀏覽、編輯頁面類似,當然功能要簡單得多。

「腳手架」有什麼實用價值,眾說紛紜。但普遍認同的一點就是「腳手架」功能為處於開發初期的應用程式提供了管理資料的介面。開發者可以在後期替換掉「腳手架」的介面。

但是,codeigniter 也太簡單了,就只有 crud 操作,還不如 phpmyadmin 好用。

其他codeigniter 還有許多其他的類和助手。這些類基本上都屬於提供各種輔助服務的範疇。有些類很不錯,像操作。但大部分類和助手實在太簡單,缺乏實用價值。像資料驗證助手,只能做很基本的驗證,在絕大多數應用程式裡面都不能滿足要求。

CodeIgniter框架介紹

入口 index.php 一些路徑常量定義 codeigniter.php 1.初始化一些 system core內的類,例如config,utf8,uri 和router等,router.set routing 處理路由對映。2.全域性函式get instance,取controller例項引用,...

Codeigniter 基本配置

config base url config index page index.php codeigniter 根目錄下的 index.php 檔名,codeigniter 會使用它來生成鏈結位址。如果使用隱藏 index.php 的 url,將其設定為空字串 config index page c...

敏捷 PHP 框架 CodeIgniter

codeigniter 是一套給 php 開發者使用的應用程式開發框架和工具包。她提供一套豐富的標準庫以及簡單的介面和邏輯結構,其目的是使開發人員更快速地進行專案開發。使用 codeigniter 可以減少 的編寫量,並將你的精力投入到專案的創造性開發上。她是乙個小巧但功能強大的 php 框架,作為...