W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
美國著名棒球運(yùn)動員約格.貝拉說過:“通過仔細(xì)地觀察,你可以了解很多事情?!?/em>
框架應(yīng)該都會考慮這樣一個(gè)問題:到底是應(yīng)該給應(yīng)用項(xiàng)目提供統(tǒng)一固定的入口和初始化流程呢,還是應(yīng)該給他們完全自由的空間?
但我發(fā)現(xiàn),很多PHP的框架都提供了一個(gè)絕對的固化流程。也就是你能作出改動的地方很少,雖然這樣應(yīng)用不需要過多地去考慮。
然而我覺得,這樣做,弊大于利。特別在現(xiàn)在項(xiàng)目需求背景各有各的不同時(shí)。所以,我為PhalApi框架選擇了開放式的初始化做法??紤]到若開放的度太大,項(xiàng)目可能會迷茫,所以又結(jié)合了統(tǒng)一的初始化。
下面分別說明這兩點(diǎn):開放式入口和封閉式的初始化。
作為一個(gè)接口系統(tǒng),是需要為不同的終端、不同的開放人群,甚至不同的版本提供不同的服務(wù)的。
如:
基于此,為不同的維度提供不同的入口就很有現(xiàn)實(shí)實(shí)用場景了。
更為重要的是,這些不同的入口都應(yīng)該盡可能簡單,并能統(tǒng)一共享公共的組件資源、數(shù)據(jù)庫、日志系統(tǒng)這些。一個(gè)可能的入口示例如下:
<?php
/**
* Demo 統(tǒng)一入口
*/
require_once dirname(__FILE__) . '/../init.php';
//裝載你的接口
DI()->loader->addDirs('Demo');
/** ---------------- 響應(yīng)接口請求 ---------------- **/
$api = new PhalApi();
$rs = $api->response();
$rs->output();
簡單解讀一下上面的代碼,首先要加載統(tǒng)一初始化文件,其實(shí)裝載掛靠的接口項(xiàng)目(對應(yīng)你的項(xiàng)目目錄的名稱),最后創(chuàng)建一個(gè)PhalApi接口實(shí)例進(jìn)行響應(yīng)、輸出結(jié)果。
下面來看下統(tǒng)一初始化文件需要做的事情。
不言而喻,盡管我們有按不同維度劃分入口的需要,但統(tǒng)一初始化的過程更是必不可少的。
不同的入口提供了各維度定制的機(jī)會,統(tǒng)一的初始化則為應(yīng)用提供了統(tǒng)一定制的機(jī)會。
常規(guī)的入口,需要以下初始化操作:
<?php
/**
* 統(tǒng)一初始化
*/
/** ---------------- 根目錄定義,自動加載 ---------------- **/
date_default_timezone_set('Asia/Shanghai');
defined('API_ROOT') || define('API_ROOT', dirname(__FILE__) . '/..');
require_once API_ROOT . '/PhalApi/PhalApi.php';
$loader = new PhalApi_Loader(API_ROOT);
/** ---------------- 注冊&初始化服務(wù)組件 ---------------- **/
//自動加載
DI()->loader = $loader;
//配置
DI()->config = new PhalApi_Config_File(API_ROOT . '/Config');
//日志紀(jì)錄
DI()->logger = new PhalApi_Logger_File(API_ROOT . '/Runtime',
PhalApi_Logger::LOG_LEVEL_DEBUG | PhalApi_Logger::LOG_LEVEL_INFO | PhalApi_Logger::LOG_LEVEL_ERROR);
//數(shù)據(jù)操作 - 基于NotORM,$_GET['__sql__']可自行改名
DI()->notorm = function() {
$debug = !empty($_GET['__sql__']) ? true : false;
return new PhalApi_DB_NotORM(DI()->config->get('dbs'), $debug);
};
//調(diào)試模式,$_GET['__debug__']可自行改名
DI()->debug = !empty($_GET['__debug__']) ? true : DI()->config->get('sys.debug');
//翻譯語言包設(shè)定
SL('zh_cn');
上面是框架執(zhí)行所需的基礎(chǔ)服務(wù)注冊和配置,一般直接可用,但也可以根據(jù)需要作些細(xì)微的調(diào)整。如日志的級別設(shè)定、調(diào)試的參數(shù)修改(改成一個(gè)只有自己知道的參數(shù)名字,別讓外界知道!)等。
出于讓大家對初始化過程有一個(gè)更理性的認(rèn)識,這里補(bǔ)充一下各代碼的作用。
最開始是利用了PHP原生態(tài)的時(shí)區(qū)設(shè)置和宏定義:
date_default_timezone_set('Asia/Shanghai');
defined('API_ROOT') || define('API_ROOT', dirname(__FILE__) . '/..');
接著,便開始引入PhalApi框架的類自動加載器:
require_once API_ROOT . '/PhalApi/PhalApi.php';
$loader = new PhalApi_Loader(API_ROOT);
這樣,我們就可以從原生態(tài)的PHP開發(fā),切入到了PhalApi接口開發(fā)模式。但在捲起袖口準(zhǔn)備大干一場前,我們還需要注冊一些必備的服務(wù):
//自動加載
DI()->loader = $loader;
//配置
DI()->config = new PhalApi_Config_File(API_ROOT . '/Config');
//日志紀(jì)錄
DI()->logger = new PhalApi_Logger_File(API_ROOT . '/Runtime',
PhalApi_Logger::LOG_LEVEL_DEBUG | PhalApi_Logger::LOG_LEVEL_INFO | PhalApi_Logger::LOG_LEVEL_ERROR);
//數(shù)據(jù)操作 - 基于NotORM,$_GET['__sql__']可自行改名
DI()->notorm = function() {
$debug = !empty($_GET['__sql__']) ? true : false;
return new PhalApi_DB_NotORM(DI()->config->get('dbs'), $debug);
};
上面的自動加載、配置、日志和數(shù)據(jù)庫操作通常而言,對于一個(gè)項(xiàng)目都是必須的。
但配置文件的路徑可自行指定,日志的存儲類型也可以自由組合(多個(gè)類型采用或運(yùn)算),還可以選擇你合適的數(shù)據(jù)庫配置。注意到,PhalApi_DB_NotORM初始化時(shí),除了配置文件外,還有一個(gè)debug參數(shù),此參數(shù)的作用是用于控制是否打印顯示執(zhí)行的SQL語句及對應(yīng)消耗的時(shí)間。
至此,我們已經(jīng)為項(xiàng)目完成了絕大部分的基礎(chǔ)服務(wù)注冊,且上面的初始化順序建議保留不變。因?yàn)?,前后有依賴關(guān)系。
但為了讓我們的項(xiàng)目更有活力、更具生氣、更國際化,我們還可以多加這么兩行代碼:
//調(diào)試模式,$_GET['__debug__']可自行改名
DI()->debug = !empty($_GET['__debug__']) ? true : DI()->config->get('sys.debug');
//翻譯語言包設(shè)定
SL('zh_cn');
這里,也有一個(gè)debug參數(shù),之所以和數(shù)據(jù)庫的分開,是因?yàn)槿绻煸谝黄饡?dǎo)致返回結(jié)果解析失敗(如不再是JSON格式)。
此debug的來源,默認(rèn)來自環(huán)境的系統(tǒng)配置文件(如區(qū)分生產(chǎn)環(huán)境和測試環(huán)境);也可以來自某個(gè)請求的手動設(shè)置,這樣,開發(fā)同學(xué)便可以快速進(jìn)行在線調(diào)試了。而這個(gè)參數(shù),則是框架代碼、項(xiàng)目代碼以及擴(kuò)展類庫所共用的調(diào)試開關(guān),至于各個(gè)場景使用的效果,視各環(huán)節(jié)而定。
SL()是一個(gè)快速函數(shù),作用是設(shè)定翻譯語言包。如果覺得中文下的UTF-8查看不直觀,可以自行加個(gè)參數(shù)修改,如:
SL(isset($_GET['__lan__']) ? $_GET['__lan__'] : 'zh_cn');
上面的操作,涵蓋了大部分項(xiàng)目的需要。除此之外,還有一些額外的服務(wù),可根據(jù)自身的情況,定制處理:
/** ---------------- 以下服務(wù)組件就根據(jù)需要定制注冊 ---------------- **/
//緩存 - MC
/**
DI()->cache = function() {
$mc = new PhalApi_Cache_Memcached(DI()->config->get('sys.mc'));
return $mc;
};
*/
//簽名驗(yàn)證服務(wù)
//DI()->filter = 'Common_SignFilter';
//支持JsonP的返回
if (!empty($_GET['callback'])) {
DI()->response = new PhalApi_Response_JsonP($_GET['callback']);
}
此部分的注冊,非項(xiàng)目必須部分。可根據(jù)需要,自行定制。
如上面出現(xiàn)的第一個(gè),即緩存服務(wù),使用的是Memcached:
DI()->cache = function() {
$mc = new PhalApi_Cache_Memcached(DI()->config->get('sys.mc'));
return $mc;
};
接下來的,是重要的接口簽名驗(yàn)證服務(wù)。之所以沒有提供這個(gè)服務(wù)的實(shí)現(xiàn),是出于更高安全性考慮而建議項(xiàng)目各自制定簽名規(guī)則并實(shí)現(xiàn)。然后這樣簡單注冊即可被框架自動調(diào)用:
//簽名驗(yàn)證服務(wù)
//DI()->filter = 'Common_SignFilter';
在有些需要支持JsonP返回的場景,可以使用PhalApi_Response_JsonP返回格式開放callback操作:
//支持JsonP的返回
if (!empty($_GET['callback'])) {
DI()->response = new PhalApi_Response_JsonP($_GET['callback']);
}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: