- ThinkPHP實戰
- 夏磊
- 600字
- 2020-11-28 18:26:51
2.2 配置操作
針對配置的操作無非讀寫而已,ThinkPHP提供了很方便的配置操作函數C(大寫字母C)。ThinkPHP按照2.1節的順序加載完配置之后,配置全局有效,在框架作用范圍內(一般指應用目錄下),所有配置都可以直接使用C函數讀取(包括ThinkPHP默認配置)。
在UPUPW的htdocs目錄中新建一個Web項目(筆者的Web項目名稱為thinkphp-inaction),目錄結構如下:
├─chapter-2 ├─index.php ├─ThinkPHP
ThinkPHP框架放在入口文件上一級主要是為了多個項目共用一套框架,節約了磁盤空間。
入口文件定義如下(以后如果沒有特殊說明,項目入口文件統一為該文件):
<? php /** * index.php */ // 檢測PHP環境 if (version_compare(PHP_VERSION, '5.3.0', '<')) die('require PHP >5.3.0 ! '); // 開啟調試模式 建議開發階段開啟 部署階段注釋或者設為false define('APP_DEBUG', true); // 定義應用目錄 define('APP_PATH', './Application/'); //關閉目錄保護 define('BUILD_DIR_SECURE', false); // 引入ThinkPHP入口文件 require '../ThinkPHP/ThinkPHP.php';
打開瀏覽器,在地址欄輸入localhost/chapter-2進行測試。看到“歡迎使用ThinkPHP! ”字樣證明應用初始化成功。
2.2.1 C函數
作為配置操作的一個重要函數,不得不單獨提下C函數。打開文件ThinkPHP/Common/functions.php,可以看到C函數定義如下:
/** * 獲取和設置配置參數 支持批量定義 * @param string|array $name配置變量 * @param mixed $value配置值 * @param mixed $default默認值 * @return mixed */ function C($name=null, $value=null, $default=null) { static $_config = array(); // 無參數時獲取所有 if (empty($name)) { return $_config; } // 優先執行設置獲取或賦值 if (is_string($name)) { if (! strpos($name, '.')) { $name = strtoupper($name); if (is_null($value)) return isset($_config[$name]) ? $_config[$name] : $default; $_config[$name] = $value; return null; } // 二維數組設置和獲取支持 $name = explode('.', $name); $name[0] = strtoupper($name[0]); if (is_null($value)) return isset($_config[$name[0]][$name[1]]) ? $_config[$name[0]][$name[1]] : $default; $_config[$name[0]][$name[1]] = $value; return null; } // 批量設置 if (is_array($name)){ $_config = array_merge($_config, array_change_key_case($name, CASE_UPPER)); return null; } return null; // 避免非法參數 }
可以看到ThinkPHP的注釋是很詳盡的,就算是沒有使用過C函數的程序員,看完注釋之后對C函數的使用方法應該是沒有問題的。C語言函數算法說明如下:
(1)定義static $_config變量,static方式定義的變量本次請求內全局有效。
(2)如果傳入的$name為空,返回所有配置;如果不為空,進入第3步。
(3)判斷$name是否為字符串,如果是,進入第4步;否則進入第12步。
(4)判斷$name中是否有“.”,如果沒有,進入第5步;否則進入第8步。
(5)將$name轉換為大寫,如果$value為null,進入第6步;否則進入第7步。
(6)判斷是否存在名為$name的配置,如果存在,則返回該配置的值;否則返回默認值。
(7)將名稱為$name的配置值設為$value,并返回null。
(8)將$name分割為數組,加入傳入的$name為“user.name”,分割完之后$name為[‘user', 'name']。
(9)將$name數組的第1個元素“user”轉換為大寫,如果傳入的$value為null,則進入第10步,否則進入第11步。
(10)判斷是否存在$_config[$name[0]][$name[1]](本例中為$_config[‘user'][‘name'])的配置,如果存在,返回$_config[$name[0]][$name[1]]的值,否則返回null。
(11)將名稱為$_config[$name[0]][$name[1]](本例中為$_config[‘user'][‘name'])的配置值設為$value,并返回null。
(12)如果$name是數組,則將該數組的全部鍵名轉換為大寫后合并到全局配置中去。
(13)最后返回null是為了防止非法調用函數。
通過源碼分析發現,ThinkPHP的配置名稱只有一級是不區分大小寫的,也就是說C(‘DATA_CACHE_TYPE')和C(‘data_cache_type')的返回值是相等的,但是二級配置是區分大小寫的,也就是說C(‘user.name')和C(‘user.NAME')是不相等的,這點請讀者注意。另外,關于無限級配置,因為源碼中可以看到ThinkPHP在對配置的處理只處理到二級,不支持二級以上配置。
2.2.2 讀取配置
打開Application/Home/Controller/IndexController.class.php,更改index方法中代碼如下:
<? php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index() { echo C('DATA_CACHE_TYPE'); } }
刷新瀏覽器,可以看到瀏覽器輸出了“File”,證明讀取配置成功,我們并沒有配置DATA_CACHE_TYPE,通過2.1節的加載順序可以發現默認配置中有DATA_CACHE_TYPE的配置。
現在開始測試公共配置的加載,打開Application/Common/Conf/config.php,設置DATA_CACHE_TYPE如下:
<? php /** * config.php */ return array( 'DATA_CACHE_TYPE' => 'Db' );
刷新瀏覽器,可以看到瀏覽器輸出了“Db”,公共配置已經覆蓋了默認的配置“File”。
繼續編輯該文件,這次添加一個二維數組,最終代碼如下:
<? php /** * config.php */ return array( 'DATA_CACHE_TYPE' => 'Db', 'ADMIN' => array( 'username' => 'admin', 'password' => '123456' ) );
打開Application/Home/IndexController.class.php,編輯index.php代碼如下:
<? php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index() { echo 'username: ' . C('ADMIN.username') . ', password: ' . C('ADMIN.password'); } }
刷新瀏覽器,可以看到瀏覽器輸出了“username: admin, password: 123456”,其他類型的配置讀取操作與本節一致。
2.2.3 加載擴展配置
在Application/Home/Conf目錄下新建admin_user.php,文件內容如下:
<? php /** * admin_user.php */ return array( array( 'id' => 1, 'username' => 'root', 'password' => 'root' ), array( 'id' => 2, 'username' => 'admin', 'password' => 'admin' ) );
編輯同級的config.php,內容如下:
<? php /** * config.php */ return array( 'LOAD_EXT_CONFIG' => array('ADMIN' => 'admin_user') );
編輯Application/Home/Controller/IndexController.class.php,代碼如下:
<? php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index() { print_r(C('ADMIN')); } }
刷新瀏覽器,如果看到如圖2-1所示結果,證明設置成功。

圖2-1
如果看到其他結果,請檢查文件路徑是否一致,如果仍不能解決問題,請前往github提問。
2.2.4 寫入配置
C函數寫入的配置屬于“動態配置”,也就是最高優先級的配置,編輯Application/Home/Controller/IndexController.class.php,內容如下:
class IndexController extends Controller { public function index() { echo '<pre>'; echo "設置前:\n"; print_r(C('ADMIN')); C('ADMIN', array( array( 'id' => 1, 'username' => 'root', 'password' => 'admin' ) )); echo "設置后:\n"; print_r(C('ADMIN')); echo '</pre>'; } }
正式輸出前后先輸出“<pre>”有利于排版顯示。
刷新瀏覽器可以看到如圖2-2所示頁面。

圖2-2
讀者可能注意到設置后的配置覆蓋掉了原來的值,如果想保留原來的值應該怎么操作呢?ThinkPHP這次就沒有提供相關函數給我們了,我們可以利用array_merge函數操作。
編輯Application/Home/Controller/IndexController.class.php,代碼如下:
<? php namespace Home\Controller; use Think\Controller; class IndexController extends Controller { public function index() { echo '<pre>'; echo "設置前:\n"; $admin = C('ADMIN'); print_r($admin); $newAdmin = array( array( 'id' => 1, 'username' => 'root', 'password' => 'admin' ) ); C('ADMIN', $newAdmin); echo "覆蓋模式設置后:\n"; print_r(C('ADMIN')); $admin = array_merge($admin, $newAdmin); echo "合并模式設置后:\n"; print_r($admin); echo '</pre>'; } }
刷新瀏覽器,可以看到如圖2-3所示界面。

圖2-3
二級配置的寫入操作和讀取類似,這里筆者就不贅述了。
- Mastering Visual Studio 2017
- Oracle從新手到高手
- 深入淺出Java虛擬機:JVM原理與實戰
- OpenStack Cloud Computing Cookbook(Fourth Edition)
- Mastering RStudio:Develop,Communicate,and Collaborate with R
- SQL基礎教程(視頻教學版)
- Elasticsearch Server(Third Edition)
- Swift語言實戰精講
- MySQL入門很輕松(微課超值版)
- Maker基地嘉年華:玩轉樂動魔盒學Scratch
- Learning iOS Security
- 并行編程方法與優化實踐
- Hands-On Dependency Injection in Go
- 量子計算機編程:從入門到實踐
- 例說FPGA:可直接用于工程項目的第一手經驗