CI框架淺析(全篇)

    業餘花了點時間看看CodeIgniter框架(簡稱CI),CI目前的穩定版本是 3.X,4.0版本已經出來了,但還在測試中,因此我分析的仍是 3.x 版本。
CI是一個很輕便的框架,整個下載包也就2M多,並且使用起來方便快捷,適用於一些簡單的功能開發,以及作app 接口。
 
    該框架整個流程圖以下:
  1. index.php 文件做爲前端控制器,初始化運行 CodeIgniter 所需的基本資源;
  2. Router 檢查 HTTP 請求,以肯定如何處理該請求;
  3. 若是存在緩存文件,將直接輸出到瀏覽器,不用走下面正常的系統流程;
  4. 在加載應用程序控制器以前,對 HTTP 請求以及任何用戶提交的數據進行安全檢查;
  5. 控制器加載模型、核心類庫、輔助函數以及其餘全部處理請求所需的資源;
  6. 最後一步,渲染視圖併發送至瀏覽器,若是開啓了緩存,視圖被會先緩存起來用於 後續的請求。
 
下載框架源碼,解壓獲得以下代碼結構:
 
 

主要有三個目錄javascript

一、application目錄:用於開發者編寫相應的配置以及邏輯處理,開發者只需在這個目錄下添加本身須要的開發文件。php

二、system目錄:框架的系統庫,裏面包括核心庫,類庫,輔助類庫,數據庫等,這些文件,開發者最好不要擅自修改,它是整個框架的龍脈。html

三、user_guide:用戶手冊。前端

 
接下來看看源碼的請求流程:
 
 
首先假設有一個 URL 請求,入口就是 index.php,該文件定義了幾個常量,應用的路徑,以及核心庫的路徑等。
 
接着引入 核心庫system/core下的 CodeIgniter.php文件,該文件初始化核心庫system/core裏的類庫,分別是:
{
  ● benchmark: "Benchmark",
  ● hooks: "Hooks",
  ● config: "Config",
  ● log: "Log",
  ● utf8: "Utf8",
  ● uri: "URI",
  ● router: "Router",
  ● output: "Output",
  ● security: "Security",
  ● input: "Input",
  ● lang: "Lang",
  ● loader: "Loader"
}

每一個類庫的註釋在上圖已有解釋。java

     同時也加載 應用項目 application/config目錄下的配置文件(這些配置文件都是開發者根據本身的須要去添加與配置),
根據判斷加載字符串處理庫mbstring,添加錯誤異常預處理方法。在加載的同時,也把鉤子部署到了相應位置,若是開發者定義了相應鉤子實現方法,就會在相應的位置執行。
    在 CodeIgniter.php 初始化核心庫的時候定義了五個鉤子,分別以下:
 
  • pre_system 在系統執行的早期調用,這個時候只有 基準測試類 和 鉤子類 被加載了, 尚未執行到路由或其餘的流程。
  • pre_controller 在你的控制器調用以前執行,全部的基礎類都已加載,路由和安全檢查也已經完成。
  • post_controller_constructor 在你的控制器實例化以後當即執行,控制器的任何方法都還還沒有調用。
  • post_controller 在你的控制器徹底運行結束時執行。
  • post_system 在最終的頁面發送到瀏覽器以後、在系統的最後期被調用。
而後,實例化 CI_Controller 類:
function &get_instance()
{
      return CI_Controller::get_instance();
}
 
經過路由 router 及 uri 獲得請求的 controller控制器、method方法 以及參數,執行該方法。
 
期間根據開發者在application/config目錄下的配置,會加載相應的 librays 類庫、 helper輔助函數 及 DB 庫。
 
若是你喜歡MVC的開發模式,也能夠添加model類,而後加載 model 模型類,處理相應的業務邏輯。
 
最後在本身定義的controller控制器處理好的數據結果渲染在html 頁面上,展現給用戶。
 
 
下面看一下CI框架幾個重要部分:
 
控制器
    開發者在 application/controller 目錄下添加本身的controller 控制器,可是每一個控制器都要繼承核心庫裏的基類 CI_Controller,它已獲取到整個框架的核心類庫對象,經過它基本能夠調用CI框架下的核心方法。
 
模型
     模型就是專門用來和數據庫打交道的 PHP 類,開發者在 application/models 目錄下定義本身的模型類,都要繼承 模型基類 CI_Mode。當你在控制下調用模型,只須要下面一行代碼就實例化了:
$this->load->model('model_name');
 
輔助函數
固然開發者也能夠建立本身的輔助類,文件存放在 application/helpers 目錄下,調用的方式與系統
的輔助類一致。
 
$this->load 就是 Loader.php 文件CI_Load 類實例, 咱們來看看 CI_Load 類下的 helper() 函數:
/**
     * Helper Loader
     *
     * @param    string|string[]    $helpers    Helper name(s)
     * @return    object
     */
    public function helper($helpers = array())
    {
        is_array($helpers) OR $helpers = array($helpers);
        foreach ($helpers as &$helper)
        {
            $filename = basename($helper);
            $filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename));
            $filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)).'_helper';
            $helper   = $filepath.$filename;

            if (isset($this->_ci_helpers[$helper]))
            {
                continue;
            }

            // Is this a helper extension request?
            $ext_helper = config_item('subclass_prefix').$filename;
            $ext_loaded = FALSE;
            foreach ($this->_ci_helper_paths as $path)
            {
                if (file_exists($path.'helpers/'.$ext_helper.'.php'))
                {
                    include_once($path.'helpers/'.$ext_helper.'.php');
                    $ext_loaded = TRUE;
                }
            }

            // If we have loaded extensions - check if the base one is here
            if ($ext_loaded === TRUE)
            {
                $base_helper = BASEPATH.'helpers/'.$helper.'.php';
                if ( ! file_exists($base_helper))
                {
                    show_error('Unable to load the requested file: helpers/'.$helper.'.php');
                }

                include_once($base_helper);
                $this->_ci_helpers[$helper] = TRUE;
                log_message('info', 'Helper loaded: '.$helper);
                continue;
            }

            // No extensions found ... try loading regular helpers and/or overrides
            foreach ($this->_ci_helper_paths as $path)
            {
                if (file_exists($path.'helpers/'.$helper.'.php'))
                {
                    include_once($path.'helpers/'.$helper.'.php');

                    $this->_ci_helpers[$helper] = TRUE;
                    log_message('info', 'Helper loaded: '.$helper);
                    break;
                }
            }

            // unable to load the helper
            if ( ! isset($this->_ci_helpers[$helper]))
            {
                show_error('Unable to load the requested file: helpers/'.$helper.'.php');
            }
        }

        return $this;
    }
     這段代碼主要是 加載(include_once) system/helpers 與 appliation/helpers 目錄下的 $name_helper.php 名稱文件,自定義的輔助函數文件須要添加 前綴 來與 系統的輔助函數區分開。當執行完加載函數,就能獲得 $this->name 實例,而後調用它裏面的函數。
全部輔助函數以下:
 
CI 類庫
 
全部的系統類庫都位於 system/libraries/ 目錄下,大多數狀況下,在使用以前, 你要先在控制器中初始化它,使用下面的方法:
$this->load->library('class_name');
'class_name' 是你想要調用的類庫名稱,例如,要加載 表單驗證類庫,你能夠這樣作:
$this->load->library('form_validation');
一旦類庫被載入,你就能夠根據該類庫的用戶指南中介紹的方法去使用它了,這個相似於輔助函數。
一樣拓展本身的類庫也是在application/libraries 目錄下。
 
一旦加載,你就可使用小寫字母名稱來訪問你的類,調用方法:
$this->someclass->some_method();
全部的類庫以下:

數據庫

     CI框架封裝了多種數據庫驅動與鏈接方法,讓你輕鬆配置就能鏈接上,且封裝了一些查詢構造器與生成查詢結果,讓代碼看起來方便簡潔。
你只需 在application/config/database.php 文件下配置你連接的參數:
$db['default'] = array(
    'dsn'    => '',
    'hostname' => 'localhost',
    'username' => '',
    'password' => '',
    'database' => '',
    'dbdriver' => 'mysqli',
    'dbprefix' => '',
    'pconnect' => FALSE,
    'db_debug' => (ENVIRONMENT !== 'production'),
    'cache_on' => FALSE,
    'cachedir' => '',
    'char_set' => 'utf8',
    'dbcollat' => 'utf8_general_ci',
    'swap_pre' => '',
    'encrypt' => FALSE,
    'compress' => FALSE,
    'stricton' => FALSE,
    'failover' => array(),
    'save_queries' => TRUE
);
而後在 Controller 裏調用一句 :$this->load->database(); 就能鏈接上數據庫。
接着,你能夠查詢你想要的結果:
$this->db->where('name',$name);
$query=$this->db->get('mytable',10,20);
// Executes: SELECT * FROM mytable where name=$nameLIMIT 20, 10
CI框架也提供了數據庫的事務處理,如:
$this->db->trans_start();$this->db->query('AN SQL QUERY...');$this->db->query('ANOTHER QUERY...');$this->db->query('AND YET ANOTHER QUERY...');$this->db->trans_complete();
 

提供了簡單的查詢緩存:

將查詢結果對象會被序列化並保存到服務器上的一個文本文件中。 當下次再訪問該頁面時,會直接使用緩存文件而不用訪問數據庫了。只有讀類型(SELECT)的查詢能夠被緩存。 這個相對應 Java 的hibernate 數據庫映射 就弱化了不少,Java提供了三級的緩存方式,並且在查詢數據庫的時候,並不會每次都斷開,再鏈接。
 
以上都是CI框架提供的重要組成部分,也許它可能知足不了你全部的需求,但也提供了一些給你拓展的方式,如在application/core目錄下添加你的核心類,這都是CI框架已考慮到的問題。固然它在處理一些繁雜的業務邏輯的時候,仍是比較薄弱的,好比說權限使用,模塊靈活增刪等。
CI框架主要是以輕便,快捷上手爲主要的優點,讓你去處理一些簡單的項目。它介於一個沒有框架與一個比較笨重的框架之間,因此一個框架好很差用,還要基於你的需求。
 
CI框架還提供了一些其它便捷的開發幫助,它有有本身的模板引擎,也有程序分析:
你能夠在你的 控制器 方法的任何位置添加一行下面的代碼:
$this->output->enable_profiler(TRUE);
 
設置基準測試點
$this->benchmark->mark('code_start');// Some code happens here$this->benchmark->mark('code_end');echo$this->benchmark->elapsed_time('code_start','code_end');
 
最後輸出分析的信息:
$sections=array('config'=>TRUE,'queries'=>TRUE);
$this->output->set_profiler_sections($sections);
 
下表列出了可用的分析器字段和用來訪問這些字段的 key :
Key Description Default
benchmarks 在各個計時點花費的時間以及總時間 TRUE  
config CodeIgniter 配置變量 TRUE  
controller_info 被請求的控制器類和調用的方法 TRUE  
get 請求中的全部 GET 數據 TRUE  
http_headers 本次請求的 HTTP 頭部 TRUE  
memory_usage 本次請求消耗的內存(單位字節) TRUE  
post 請求中的全部 POST 數據 TRUE  
queries 列出全部執行的數據庫查詢,以及執行時間 TRUE  
uri_string 本次請求的 URI TRUE  
session_data 當前會話中存儲的數據 TRUE  
query_toggle_count 指定顯示多少個數據庫查詢,剩下的則默認摺疊起來 25  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
以上是我對CI框架大體的瞭解與分析,我作php的經驗很少,這是我第一個嘗試去深刻了解的php框架,請你們多多指教。
相關文章
相關標籤/搜索