ThinkPHP應用模式擴充之謎
ThinkPHP應用模式提供了對核心架構進行改造的機會,可以讓你的應用適應更多的環境和不同的需求。每個應用模式都有自己的模式定義檔案,相對與ThinkPHP3.1版本,ThinkPHP3.2版本對應用模式的擴充更加明確和清晰,在ThinkPHP3.1版本中定義了Cli、Lite、Thin、AMF、PHPRPC、REST模式,其定義方式和ThinkPHP3.2版本的方式大同小異,如有需要可以參考修改,其中Cli模式被ThinkPHP架構內建,不用單獨定義Cli模式即可正常使用,如需要更細化調整可以參考3.1版編寫的Cli運行模式擴充。ThinkPHP同樣提供了便捷的開發環境和正式環境的模式切換方式。讓我們隨著ThinkPHP的運行流程解析其應用模式擴充之謎。
一、應用模式的使用
在研究應用模式擴充之前,看看如何使用應用模式的吧。一般通過在入口檔案定義常量APP_MODE為應用模式名稱,但是在分析ThinkPHP架構入口檔案時,瞭解到架構預設採用模式為普通模式(common),而且可以自動識別sae環境,當然前提是沒有定義APP_MODE常量時,當然ThinkPHP可以自動識別CLI和CGI模式,並且在CLI和CGI環境下運行ThinkPHP架構在預設模式中自動對這兩種環境做了細微調整,當然也可以自己擴充這兩種應用模式。
if(function_exists('saeAutoLoader')){// 自動識別SAE環境 defined('APP_MODE') or define('APP_MODE', 'sae'); defined('STORAGE_TYPE') or define('STORAGE_TYPE', 'Sae');}else{ defined('APP_MODE') or define('APP_MODE', 'common'); // 應用模式 預設為普通模式 defined('STORAGE_TYPE') or define('STORAGE_TYPE', 'File'); // 儲存類型 預設為File }
二、應用模式定義
在ThinkPHP架構當中除了ThinkPHP架構入口和架構引導類以外,基本所有其他功能都可以通過應用模式變更和擴充,如果我們要增加一個應用模式,只需要在ThinkPHP\Mode目錄下面定義一個模式定義檔案即可,我們可以通過分析common模式進行學習。
//檔案路徑:ThinkPHP/Mode/common.php/** * ThinkPHP 普通模式定義 * 定義一個模式檔案,只需要返回一個模式包含檔案的數組即可 * 在數組中主要包含4種擴充檔案清單: * config 為預設載入設定檔列表 * alias 為核心類庫別名配置列表 * core 需要載入的核心函數和類檔案清單 * tags 行為配置列表 * * 如果在應用模式定義中載入一個自定類,那個自訂類的命名空間必須是Think */return array( // 設定檔 'config' => array( THINK_PATH.'Conf/convention.php', // 系統慣例配置 CONF_PATH.'config.php', // 應用公用配置 ), // 別名定義 'alias' => array( 'Think\Log' => CORE_PATH . 'Log'.EXT, 'Think\Log\Driver\File' => CORE_PATH . 'Log/Driver/File'.EXT, 'Think\Exception' => CORE_PATH . 'Exception'.EXT, 'Think\Model' => CORE_PATH . 'Model'.EXT, 'Think\Db' => CORE_PATH . 'Db'.EXT, 'Think\Template' => CORE_PATH . 'Template'.EXT, 'Think\Cache' => CORE_PATH . 'Cache'.EXT, 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File'.EXT, 'Think\Storage' => CORE_PATH . 'Storage'.EXT, ), // 函數和類檔案 'core' => array( THINK_PATH.'Common/functions.php', COMMON_PATH.'Common/function.php', CORE_PATH . 'Hook'.EXT, CORE_PATH . 'App'.EXT, CORE_PATH . 'Dispatcher'.EXT, //CORE_PATH . 'Log'.EXT, CORE_PATH . 'Route'.EXT, CORE_PATH . 'Controller'.EXT, CORE_PATH . 'View'.EXT, BEHAVIOR_PATH . 'BuildLiteBehavior'.EXT, BEHAVIOR_PATH . 'ParseTemplateBehavior'.EXT, BEHAVIOR_PATH . 'ContentReplaceBehavior'.EXT, ), // 行為擴充定義 'tags' => array( 'app_init' => array( 'Behavior\BuildLiteBehavior', // 產生運行Lite檔案 ), 'app_begin' => array( 'Behavior\ReadHtmlCacheBehavior', // 讀取靜態緩衝 ), 'app_end' => array( 'Behavior\ShowPageTraceBehavior', // 頁面Trace顯示 ), 'view_parse' => array( 'Behavior\ParseTemplateBehavior', // 模板解析 支援PHP、內建模板引擎和第三方模板引擎 ), 'template_filter'=> array( 'Behavior\ContentReplaceBehavior', // 模板輸出替換 ), 'view_filter' => array( 'Behavior\WriteHtmlCacheBehavior', // 寫入靜態緩衝 ), ),);
我們看到這個普通應用模式代碼之後,有點明了ThinkPHP的應用模式擴充是怎麼回事了,但是還是知其然而不知其所以然,定義一個負載檔案列表和配置是如何改變架構核心的呢?秘密就在ThinkPHPK引導類中,讓我們再回顧以下吧!
//判斷是否存在core.php設定檔(這是開發環境臨時定義的運行模式,我是這麼理解的) //否者載入APP_MODE定義的模式檔案 $mode = include is_file(CONF_PATH.'core.php')?CONF_PATH.'core.php':MODE_PATH.APP_MODE.'.php'; //載入模式中core定義的核心檔案清單 foreach ($mode['core'] as $file){ if(is_file($file)) { include $file; if(!APP_DEBUG) $content .= compile($file); } } //載入模式中定義的config設定檔列表 foreach ($mode['config'] as $key=>$file){ is_numeric($key)?C(include $file):C($key,include $file); } // 讀取當前應用模式對應的設定檔 if('common' != APP_MODE && is_file(CONF_PATH.'config_'.APP_MODE.'.php')) C(include CONF_PATH.'config_'.APP_MODE.'.php'); // 載入模式中alias別名列表定義 if(isset($mode['alias'])){ self::addMap(is_array($mode['alias'])?$mode['alias']:include $mode['alias']); } // 載入應用別名定義檔案 if(is_file(CONF_PATH.'alias.php')) self::addMap(include CONF_PATH.'alias.php'); // 載入模式中tags行為定義 if(isset($mode['tags'])) { Hook::import(is_array($mode['tags'])?$mode['tags']:include $mode['tags']); } // 載入應用行為定義 if(is_file(CONF_PATH.'tags.php')) // 允許應用增加開發模式配置定義 Hook::import(include CONF_PATH.'tags.php'); // 載入架構底層語言套件 L(include THINK_PATH.'Lang/'.strtolower(C('DEFAULT_LANG')).'.php');
通過ThinkPHP::start()中的這段代碼,完美無縫關聯的模式定義檔案的意義與實現方法。
三、定義簡單的運行模式
手冊中有一個模式擴充到的執行個體,可以拿到這裡來分析一下,定義一個lite簡潔運行模式,首先在ThinkPHP/Mode目錄下建立一個lite.php檔案內容定義如下:
return array( // 設定檔 'config' => array( THINK_PATH.'Conf/convention.php', // 系統慣例配置 CONF_PATH.'config.php', // 應用公用配置 ), // 別名定義 'alias' => array( 'Think\Exception' => CORE_PATH . 'Exception'.EXT, 'Think\Model' => CORE_PATH . 'Model'.EXT, 'Think\Db' => CORE_PATH . 'Db'.EXT, 'Think\Cache' => CORE_PATH . 'Cache'.EXT, 'Think\Cache\Driver\File' => CORE_PATH . 'Cache/Driver/File'.EXT, 'Think\Storage' => CORE_PATH . 'Storage'.EXT, ), // 函數和類檔案 'core' => array( MODE_PATH.'Lite/functions.php', COMMON_PATH.'Common/function.php', MODE_PATH . 'Lite/App'.EXT, MODE_PATH . 'Lite/Dispatcher'.EXT, MODE_PATH . 'Lite/Controller'.EXT, MODE_PATH . 'Lite/View'.EXT, CORE_PATH . 'Behavior'.EXT, ), // 行為擴充定義 'tags' => array( 'view_parse' => array( 'Behavior\ParseTemplate', // 模板解析 支援PHP、內建模板引擎和第三方模板引擎 ), 'template_filter'=> array( 'Behavior\ContentReplace', // 模板輸出替換 ), ),);
從上面的配置當中我們發現core中的核心檔案大多數都被替換了,當然這些需要被替換的程式功能需要我們自己去實現,不過建議大家直接拷貝普通模式中定義的核心檔案過來修改。接下來我們來實現以下ThinkPHP應用開發中的核心類庫擴充檔案App.class.php
在ThinkPHP/Mode目錄下建立一個Lite目錄並在lite目錄下建立App.class.php檔案,以下是程式檔案的實現:
//模式擴充類庫必須是Think命名空間namespace Think; /** * ThinkPHP 應用程式類 執行應用過程管理 Lite模式擴充類 * 實現ThinkPHP核心類庫擴充時,儘可能仿造原有類庫實現(除非對ThinkPHP架構源碼特別瞭解) * 因為在其他沒有擴充的核心檔案中可能會調用擴充的核心類檔案中的某個方法,除非你打算全部擴充 */class App{/** * 應用程式初始化 * @access public * @return void */static public function init() { //具體現實} /** * 執行應用程式 * @access public * @return void */static public function exec() { //具體實現} /** * 運行應用執行個體 入口檔案使用的快捷方法 * @access public * @return void */static public function run() { //具體實現} static public function logo(){ //具體實現}}
當檔案所有擴充檔案的實現後,可以在架構入口檔案定義APP_MODE常量為lite。
在這裡吐槽以下官方:本節手冊當中居然要定義MODE_NAME常量來改變運行模式,為了準確性無奈在ThinkPHP架構全部檔案中搜尋MODE_NAME,結果都沒有才放下一個懸著的心。這是之前3.1版本中定義運行模式的方法,手冊更新細節問題(聲明一下我現在用的手冊是3.2.12014年2月14日的版本)。
http://www.bkjia.com/PHPjc/845433.htmlwww.bkjia.comtruehttp://www.bkjia.com/PHPjc/845433.htmlTechArticleThinkPHP應用模式擴充之謎 ThinkPHP應用模式提供了對核心架構進行改造的機會,可以讓你的應用適應更多的環境和不同的需求。每個應用模式...