CI框架原始碼研讀(整體架構)
部落格搬家:http://chanyaw.cn
有人說phper的深入要從研讀mvc框架開始,我跳了一個常用的CI框架入手,一是因為 CI框架簡單輕巧,二是原來用的最多的就是CI框架了。
1、首先來看CI的整體架構圖:
上圖中是我最新下載CI3.0版本,application是使用者級開發目錄,我們關心system系統原始碼目錄,CI的核心程式碼都在這裡了。
1、core 系統核心程式碼
2、database資料庫相關的操作和幫助類
3、helers 系統提供的一些工具類
4、language 語言包
5、libraries 系統依賴類
2、CI的程式碼流程
我們初次訪問CI的時候進入的welcome頁面,那麼這個welcome的頁面請求都經過了哪些地方呢,我們來追蹤一下。
所以對ci的請求,都是首先進入index.php檔案。在index.php檔案中進行CI框架的初始化操作,
define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');
define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
define('BASEPATH', $system_path);
define('FCPATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
define('SYSDIR', basename(BASEPATH));
define('APPPATH', $application_folder.DIRECTORY_SEPARATOR);
define('VIEWPATH', $view_folder.DIRECTORY_SEPARATOR);
require_once BASEPATH.'core/CodeIgniter.php';
在index.php檔案中定義了必要的全域性變數,最後引入了core/CodeIgniter.php核心類。那我們追蹤到core/CodeIgniter.php中,檔案中首先引入了:
require_once(APPPATH.'config/constants.php');
require_once(BASEPATH.'core/Common.php');
之後又例項化了 Benchmark、Hooks、Config、Log、Utf8、URI、Router、Output、Security、Input、Lang 類,引入是呼叫common.php中的load_class方法實現的。
$class = ucfirst($RTR->class);
$method = $RTR->method;
在路由中提取出對應要呼叫的class和method,然後例項化class且呼叫方法:
$CI = new $class();
call_user_func_array(array(&$CI, $method), $params);
其前後呼叫了四個鉤子:
$EXT->call_hook('pre_controller');
$EXT->call_hook('post_controller_constructor');
$EXT->call_hook('post_controller');
$EXT->call_hook('post_system');
這裡解析出的class和method,其實就是Welcome和index,之後我們 進入application/controllers/Welcome.php類後發現,類裡只有
public function index(){
$this->load->view('welcome_message');
}
簡單的 載入模板方法,我們看到Welcome 類繼承自父類:CI_Controller
我們進入CI_Controller類中檢視:
public function __construct(){
self::$instance =& $this;
foreach (is_loaded() as $var => $class){
$this->$var =& load_class($class);
}$this->load =& load_class('Loader', 'core');
$this->load->initialize();
log_message('info', 'Controller Class Initialized');
}
這段建構函式是將,在引導類CodeIgniter.php被例項化化的類賦值到本地類變數中,以構造一個超級物件被使用。同時實現了一個單例 公外部呼叫。
那是如何賦值的那,這裡呼叫了 common類 中的is_loader()方法。其實就是返回的我們在上面
呼叫load_class()載入過的類:
最後初始化成功後,會執行CodeIgniter.php檔案中的:
call_user_func_array(array(&$CI, $method), $params);
這個函式,從而進入我們welcome控制器的index方法。