CI框架淺析(全篇)

来源:http://www.cnblogs.com/xiaoxiaoqingyi/archive/2017/05/24/6901654.html
-Advertisement-
Play Games

使用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. 最後一步,渲染視圖併發送至瀏覽器,如果開啟了緩存,視圖被會先緩存起來用於 後續的請求。
  下載框架源碼,解壓得到如下代碼結構:    

主要有三個目錄

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

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

3、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"
}

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

     同時也載入 應用項目 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框架,請大家多多指教。  

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • C#事件總結與應用 什麼是事件? 事件是特殊化的委托,委托是事件的基礎,所以在介紹事件之前先介紹一下委托 通俗的說就是: 事件就是消息驅動器通過委托類來調用感興趣的方法,事實上事件調用是間接的調用 就像是顯示中我的代理人一樣 發佈者與訂閱者 在學習事件的時候們首先要明白什麼是發佈者什麼是訂閱者: 通 ...
  • 一、constant 該函數可以將變數註冊在模塊中,並以服務的形式進行使用。 例如: var app = angular.module("MyModule",[]).constant("pageConfig",{pageSize:10}); 通過以上方式就定義了一個模塊中可用的pageConfig的 ...
  • CentOS上實現一鍵Maven打包並部署到Tomcat的Shell腳本 給這個Shell腳本取個名字,比如叫 deploylab, 將deploylab移到任何已經在系統環境變數的bin目錄下,如: 然後就可以在任意位置直接輸入命令 deploylab 一鍵部署最新代碼到Tomcat了。 ...
  • 在大型項目編碼推進中,涉及到 XML 解析問題時,大多數程式員都不太會選用底層的解析方式直接編碼。 主要存在編碼複雜性、難擴展、難復用....,但如果你是 super 程式員或是一個人的項目,也不妨一試。 Jdom/Dom4j/Xstream... 基於底層解析方式重新組織封裝的開源類庫,簡潔明瞭的 ...
  • 本節探討Java中的類載入機制,利用自定義的ClassLoader實現熱部署 ...
  • Myeclipse2016安裝Aptana 想裝個Aptana,裝了半天,網上說的什麼links方式啊,線上方式啊,都是什麼的浮雲。 所以自己來寫個安裝教程。 一、Aptana簡要介紹 Aptana有JavaScript,JavaScript函數,HTML,CSS語言的Code Assist功能。 ...
  • CNN神經網路架構至少包含一個捲積層 (tf.nn.conv2d)。單層CNN檢測邊緣。圖像識別分類,使用不同層類型支持捲積層,減少過擬合,加速訓練過程,降低記憶體占用率。 TensorFlow加速所有不同類弄捲積層捲積運算。tf.nn.depthwise_conv2d,一個捲積層輸出邊接到另一個捲積 ...
  • 1 導入jar包 1.1 導入Spring的開發包 1.2 導入mybatis的jar包 1.3 導入MySQL的驅動 1.4 導入mybatis與Spring的整合包 1.5 導入junit4.jar包 1.6 導入log4j.jar 1.5 導入c3p0.jar 1.6 導入spring-tes ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...