A方法
A方法用于在內(nèi)部實(shí)例化控制器,調(diào)用格式:A(‘[項(xiàng)目://][分組/]模塊','控制器層名稱(chēng)')
最簡(jiǎn)單的用法:
代碼如下:
$User = A('User');
表示實(shí)例化當(dāng)前項(xiàng)目的UserAction控制器(這個(gè)控制器對(duì)應(yīng)的文件位于Lib/Action/UserAction.class.),如果采用了分組模式,并且要實(shí)例化另外一個(gè)Admin分組的控制器可以用:
代碼如下:
$User = A('Admin/User');
也支持跨項(xiàng)目實(shí)例化(項(xiàng)目的目錄要保持同級(jí))
代碼如下:
$User = A('Admin://User');
表示實(shí)例化Admin項(xiàng)目下面的UserAction控制器
.1版本增加了分層控制器的支持,所以還可以用A方法實(shí)例化其他的控制器,例如:
代碼如下:
$User = A('User','Event);
實(shí)例化UserEvent控制器(對(duì)應(yīng)的文件位于Lib/Event/UserEvent.class.)。
實(shí)例化控制器后,就可以調(diào)用該控制器中的方法,不過(guò)需要注意的情況是,在跨項(xiàng)目調(diào)用的情況下,如果你的操作方法 有針對(duì)當(dāng)前控制器的特殊變量操作,會(huì)有一些未知的問(wèn)題,所以,一般來(lái)說(shuō),官方建議需要公共調(diào)用的控制器層單獨(dú)開(kāi)發(fā),不要有太多的依賴(lài)關(guān)系。
B方法
這是隨著行為應(yīng)運(yùn)而生的新生函數(shù),可以執(zhí)行某個(gè)行為,例如
代碼如下:
B('app_begin');
就是在項(xiàng)目開(kāi)始之前,執(zhí)行這個(gè)行為定義的所有函數(shù)。支持2個(gè)參數(shù),第二個(gè)參數(shù)支持需要接受一個(gè)數(shù)組,例如
代碼如下:
B('app_begin',array("name"=& gt;"tdweb","time"=>time()));
C方法
C方法是Think用于設(shè)置、獲取,以及保存配置參數(shù)的方法,使用頻率較高。
了解C方法需要首先了解下Think的配置,因?yàn)镃方法的所有操作都是圍繞配置相關(guān)的。Think的配置文件采用數(shù)組格式定義。
由于采用了函數(shù)重載設(shè)計(jì),所以用法較多,我們來(lái)一一說(shuō)明下。
設(shè)置參數(shù)
代碼如下:
C('DB_NAME','think');
表示設(shè)置DB_NAME配置參數(shù)的值為think,由于配置參數(shù)不區(qū)分大小寫(xiě),所以下面的寫(xiě)法也是一樣:
代碼如下:
C('db_name','think');
但是建議保持統(tǒng)一大寫(xiě)的配置定義規(guī)范。
項(xiàng)目的所有參數(shù)在未生效之前都可以通過(guò)該方法動(dòng)態(tài)改變配置,最后設(shè)置的值會(huì)覆蓋前面設(shè)置或者慣例配置里面的定義,也可以使用參數(shù)配置方法添加新的配置。
支持二級(jí)配置參數(shù)的設(shè)置,例如:
代碼如下:
C('USER.USER_ID',8);
配置參數(shù)不建議超過(guò)二級(jí)。
如果要設(shè)置多個(gè)參數(shù),可以使用批量設(shè)置,例如:
代碼如下:
$config['user_id'] = 1;
$config['user_type'] = 1;
C($config);
如果C方法的第一個(gè)參數(shù)傳入數(shù)組,就表示批量賦值,上面的賦值相當(dāng)于:
代碼如下:
C('USER_ID',1);
C('USER_TYPE',1);
獲取參數(shù)
要獲取設(shè)置的參數(shù),可以用:
代碼如下:
$userId = C('USER_ID');
$userType = C('USER_TYPE');
如果USER_ID參數(shù)尚未定義過(guò),則返回NULL。
也可以支持獲取二級(jí)配置參數(shù),例如:
代碼如下:
$userId = C('USER.USER_ID');
如果傳入的配置參數(shù)為空,表示獲取全部的參數(shù):
代碼如下:
$config = C();
保存設(shè)置
.1版本增加了一個(gè)永久保存設(shè)置參數(shù)的功能,僅針對(duì)批量賦值的情況,例如:
代碼如下:
$config['user_id'] = 1;
$config['user_type'] = 1;
C($config,'name');
在批量設(shè)置了config參數(shù)后,會(huì)連同當(dāng)前所有的配置參數(shù)保存到緩存文件(或者其他配置的緩存方式)。
保存之后,如果要取回保存的參數(shù),可以用
代碼如下:
$config = C('','name');
其中name就是前面保存參數(shù)時(shí)用的緩存的標(biāo)識(shí),必須一致才能正確取回保存的參數(shù)。取回的參數(shù)會(huì)和當(dāng)前的配置參數(shù)合并,無(wú)需手動(dòng)合并。
D方法
D方法應(yīng)該是用的比較多的方法了,用于實(shí)例化自定義模型類(lèi),是Think框架對(duì)Model類(lèi)實(shí)例化的一種封裝,并實(shí)現(xiàn)了單例模式,支持跨項(xiàng)目和分組調(diào)用,調(diào)用格式如下:
D(‘[項(xiàng)目://][分組/]模型','模型層名稱(chēng)')
方法的返回值是實(shí)例化的模型對(duì)象。
D方法可以自動(dòng)檢測(cè)模型類(lèi),如果存在自定義的模型類(lèi),則實(shí)例化自定義模型類(lèi),如果不存在,則會(huì)實(shí)例化Model基類(lèi),同時(shí)對(duì)于已實(shí)例化過(guò)的模型,不會(huì)重復(fù)去實(shí)例化。
D方法最常用的用法就是實(shí)例化當(dāng)前項(xiàng)目的某個(gè)自定義模型,例如:
代碼如下:
// 實(shí)例化User模型
$User = D('User');
會(huì)導(dǎo)入當(dāng)前項(xiàng)目下面的Lib/Model/UserModel.class.文件,然后實(shí)例化UserModel類(lèi),所以,實(shí)際上的代碼可能和下面的等效:
代碼如下:
import('@.Model.UserModel');
$User = new UserModel();
但是如果使用D方法的話,如果這個(gè)UserModel類(lèi)不存在,則會(huì)自動(dòng)調(diào)用
代碼如下:
new Model('User');
并且第二次調(diào)用的時(shí)候無(wú)需再次實(shí)例化,可以減少一定的對(duì)象實(shí)例化開(kāi)銷(xiāo)。
D方法可以支持跨分組和項(xiàng)目實(shí)例化模型,例如:
代碼如下:
//實(shí)例化Admin項(xiàng)目的User模型
D('Admin://User')
//實(shí)例化Admin分組的User模型
D('Admin/User')
注意:要實(shí)現(xiàn)跨項(xiàng)目調(diào)用模型的話,必須確保兩個(gè)項(xiàng)目的目錄結(jié)構(gòu)是并列的。
.1版本開(kāi)始,由于增加了分層模型的支持,所以D方法也可以實(shí)例化其他的模型,例如:
代碼如下:
// 實(shí)例化UserService類(lèi)
$User = D('User','Service');
// 實(shí)例化UserLogic類(lèi)
$User = D('User','Logic');
代碼如下:
D('User','Service');
會(huì)導(dǎo)入Lib/Service/UserService.class.,并實(shí)例化,等效于下面的代碼:
代碼如下:
import('@.Service.UserService');
$User = new UserSerivce();
F方法
F方法其實(shí)是S方法的一個(gè)子集功能,僅用于簡(jiǎn)單數(shù)據(jù)緩存,并且只能支持文件形式,不支持緩存有效期,因?yàn)椴捎玫氖欠祷胤绞?,所以其效率較S方法較高,因此我們也稱(chēng)之為快速緩存方法。
F方法的特點(diǎn)是:
簡(jiǎn)單數(shù)據(jù)緩存;
文件形式保存;
采用返回?cái)?shù)據(jù)方式加載緩存;
支持子目錄緩存以及自動(dòng)創(chuàng)建;
支持刪除緩存和批量刪除;
寫(xiě)入和讀取緩存
代碼如下:
F('data','test data');
默認(rèn)的保存起始路徑是DATA_PATH(該常量在默認(rèn)配置位于RUNTIME_PATH.'Data/'下面),也就是說(shuō)會(huì)生成文件名為DATA_PATH.'data.'的緩存文件。
注意:確保你的緩存標(biāo)識(shí)的唯一,避免數(shù)據(jù)覆蓋和沖突。
下次讀取緩存數(shù)據(jù)的時(shí)候,使用:
代碼如下:
$Data = F('data');
我們可以采用子目錄方式保存,例如:
代碼如下:
F('user/data',$data); // 緩存寫(xiě)入
F('user/data'); // 讀取緩存
就會(huì)生成DATA_PATH.'user/data.' 緩存文件,如果user子目錄不存在的話,則會(huì)自動(dòng)創(chuàng)建,也可以支持多級(jí)子目錄,例如:
代碼如下:
F('level1/level2/data',$data);
如果需要指定緩存的起始目錄,可以用下面的方式:
代碼如下:
F('data',$data,TEMP_PATH);
獲取的時(shí)候則需要使用:
代碼如下:
F('data','',TEMP_PATH);
刪除緩存
刪除緩存也很簡(jiǎn)單,使用:
代碼如下:
F('data',NULL);
第二個(gè)參數(shù)傳入NULL,則表示刪除標(biāo)識(shí)為data的數(shù)據(jù)緩存。
支持批量刪除功能,尤其是針對(duì)子目錄緩存的情況,假設(shè)我們要?jiǎng)h除user子目錄下面的所有緩存數(shù)據(jù),可以使用:
代碼如下:
F('user/*',NULL);
又或者使用過(guò)濾條件刪除,例如:
代碼如下:
F('user/[^a]*',NULL);
G方法
Thinkphp長(zhǎng)期以來(lái)需要通過(guò)debug_start、debug_end方法甚至Debug類(lèi)才能完成的功能,3.1版本中被一個(gè)簡(jiǎn)單的G方法取代了,不可不謂是一次華麗升級(jí)。
G方法的作用包括標(biāo)記位置和區(qū)間統(tǒng)計(jì)兩個(gè)功能,下面來(lái)看下具體用法:
標(biāo)記位置
G方法的第一個(gè)用法就是標(biāo)記位置,例如:
代碼如下:
G('begin');
表示把當(dāng)前位置標(biāo)記為begin標(biāo)簽,并且記錄當(dāng)前位置的執(zhí)行時(shí)間,如果環(huán)境支持的話,還能記錄內(nèi)存占用情況??梢栽谌魏挝恢谜{(diào)用G方法標(biāo)記。
運(yùn)行時(shí)間統(tǒng)計(jì)
標(biāo)記位置后,我們就可以再次調(diào)用G方法進(jìn)行區(qū)間統(tǒng)計(jì)了,例如:
代碼如下:
G('begin');
// ...其他代碼段
G('end');
// ...也許這里還有其他代碼
// 進(jìn)行統(tǒng)計(jì)區(qū)間
echo G('begin','end').'s';
G(‘begin','end') 表示統(tǒng)計(jì)begin位置到end位置的執(zhí)行時(shí)間(單位是秒),begin必須是一個(gè)已經(jīng)標(biāo)記過(guò)的位置,如果這個(gè)時(shí)候end位置還沒(méi)被標(biāo)記過(guò),則會(huì)自動(dòng)把當(dāng)前位置標(biāo)記為end標(biāo)簽,輸出的結(jié)果類(lèi)似于:
代碼如下:
0.0056s
默認(rèn)的統(tǒng)計(jì)精度是小數(shù)點(diǎn)后4位,如果覺(jué)得這個(gè)統(tǒng)計(jì)精度不夠,還可以設(shè)置例如:
代碼如下:
G('begin','end',6).'s';
可能的輸出會(huì)變成:
代碼如下:
0.005587s
內(nèi)存開(kāi)銷(xiāo)統(tǒng)計(jì)
如果你的環(huán)境支持內(nèi)存占用統(tǒng)計(jì)的話,還可以使用G方法進(jìn)行區(qū)間內(nèi)存開(kāi)銷(xiāo)統(tǒng)計(jì)(單位為kb),例如:
代碼如下:
echo G('begin','end','m').'kb';
第三個(gè)參數(shù)使用m表示進(jìn)行內(nèi)存開(kāi)銷(xiāo)統(tǒng)計(jì),輸出的結(jié)果可能是:
代碼如下:
625kb
同樣,如果end標(biāo)簽沒(méi)有被標(biāo)記的話,會(huì)自動(dòng)把當(dāng)前位置先標(biāo)記位end標(biāo)簽。
如果環(huán)境不支持內(nèi)存統(tǒng)計(jì),則該參數(shù)無(wú)效,仍然會(huì)進(jìn)行區(qū)間運(yùn)行時(shí)間統(tǒng)計(jì)。
忘掉debug_start、debug_end吧,大道至簡(jiǎn),你懂的~
I方法
Thinkphp的I方法是3.1.3版本新增的,如果你是之前的3.*版本的話,可以直接參考使用3.1快速入門(mén)教程系列的變量部分。
概述
正如你所見(jiàn)到的一樣,I方法是Thinkphp眾多單字母函數(shù)中的新成員,其命名來(lái)自于英文Input(輸入),主要用于更加方便和安全的獲取系統(tǒng)輸入變量,可以用于任何地方,用法格式如下:
I(‘變量類(lèi)型.變量名',[‘默認(rèn)值'],[‘過(guò)濾方法'])
變量類(lèi)型是指請(qǐng)求方式或者輸入類(lèi)型,包括:
get 獲取GET參數(shù)
post 獲取POST參數(shù)
param 自動(dòng)判斷請(qǐng)求類(lèi)型獲取GET、POST或者PUT參數(shù)
request 獲取REQUEST 參數(shù)
put 獲取PUT 參數(shù)
session 獲取 $_SESSION 參數(shù)
cookie 獲取 $_COOKIE 參數(shù)
server 獲取 $_SERVER 參數(shù)
globals 獲取 $GLOBALS參數(shù)
注意:變量類(lèi)型不區(qū)分大小寫(xiě)。
變量名則嚴(yán)格區(qū)分大小寫(xiě)。
默認(rèn)值和過(guò)濾方法均屬于可選參數(shù)。
用法
我們以GET變量類(lèi)型為例,說(shuō)明下I方法的使用:
代碼如下:
echo I('get.id'); // 相當(dāng)于 $_GET['id']
echo I('get.name'); // 相當(dāng)于 $_GET['name']
支持默認(rèn)值:
代碼如下:
echo I('get.id',0); // 如果不存在$_GET['id'] 則返回0
echo I('get.name',''); // 如果不存在$_GET['name'] 則返回空字符串
采用方法過(guò)濾:
代碼如下:
echo I('get.name','','htmlspecialchars'); // 采用htmlspecialchars方法對(duì)$_GET['name'] 進(jìn)行過(guò)濾,如果不存在則返回空字符串
支持直接獲取整個(gè)變量類(lèi)型,例如:
代碼如下:
I('get.'); // 獲取整個(gè)$_GET 數(shù)組
用同樣的方式,我們可以獲取post或者其他輸入類(lèi)型的變量,例如:
代碼如下:
1.I('post.name','','htmlspecialchars'); // 采用htmlspecialchars方法對(duì)$_POST['name'] 進(jìn)行過(guò)濾,如果不存在則返回空字符串
I('session.user_id',0); // 獲取$_SESSION['user_id'] 如果不存在則默認(rèn)為0
I('cookie.'); // 獲取整個(gè) $_COOKIE 數(shù)組
I('server.REQUEST_METHOD'); // 獲取 $_SERVER['REQUEST_METHOD']
param變量類(lèi)型是框架特有的支持自動(dòng)判斷當(dāng)前請(qǐng)求類(lèi)型的變量獲取方式,例如:
代碼如下:
echo I('param.id');
如果當(dāng)前請(qǐng)求類(lèi)型是GET,那么等效于 GET[′id′],如果當(dāng)前請(qǐng)求類(lèi)型是POST或者PUT,那么相當(dāng)于獲取_POST[‘id'] 或者 PUT參數(shù)id。
并且param類(lèi)型變量還可以用數(shù)字索引的方式獲取URL參數(shù)(必須是PATHINFO模式參數(shù)有效,無(wú)論是GET還是POST方式都有效),例如:
當(dāng)前訪問(wèn)URL地址是
代碼如下:
http://serverName/index./New/2013/06/01
那么我們可以通過(guò)
代碼如下:
echo I('param.1'); // 輸出2013
echo I('param.2'); // 輸出06
echo I('param.3'); // 輸出01
事實(shí)上,param變量類(lèi)型的寫(xiě)法可以簡(jiǎn)化為:
代碼如下:
I('id'); // 等同于 I('param.id')
I('name'); // 等同于 I('param.name')
變量過(guò)濾
使用I方法的時(shí)候 變量其實(shí)經(jīng)過(guò)了兩道過(guò)濾,首先是全局的過(guò)濾,全局過(guò)濾是通過(guò)配置VAR_FILTERS參數(shù),這里一定要注意,3.1版本之后,VAR_FILTERS參數(shù)的過(guò)濾機(jī)制已經(jīng)更改為采用array_walk_recursive方法遞歸過(guò)濾了,主要對(duì)過(guò)濾方法的要求是必須引用返回,所以這里設(shè)置htmlspecialchars是無(wú)效的,你可以自定義一個(gè)方法,例如:
代碼如下:
function filter_default(&$value){
$value = htmlspecialchars($value);
}
然后配置:
代碼如下:
'VAR_FILTERS'=>'filter_default'
如果需要進(jìn)行多次過(guò)濾,可以用:
代碼如下:
'VAR_FILTERS'=>'filter_default,filter_exp'
filter_exp方法是框架內(nèi)置的安全過(guò)濾方法,用于防止利用模型的EXP功能進(jìn)行注入攻擊。
因?yàn)閂AR_FILTERS參數(shù)設(shè)置的是全局過(guò)濾機(jī)制,而且采用的是遞歸過(guò)濾,對(duì)效率有所影響,所以,我們更建議直接對(duì)獲取變量過(guò)濾的方式,除了在I方法的第三個(gè)參數(shù)設(shè)置過(guò)濾方法外,還可以采用配置DEFAULT_FILTER參數(shù)的方式設(shè)置過(guò)濾,事實(shí)上,該參數(shù)的默認(rèn)設(shè)置是:
代碼如下:
'DEFAULT_FILTER' => 'htmlspecialchars'
也就說(shuō),I方法的所有獲取變量都會(huì)進(jìn)行htmlspecialchars過(guò)濾,那么:
代碼如下:
I('get.name'); // 等同于 htmlspecialchars($_GET['name'])
同樣,該參數(shù)也可以支持多個(gè)過(guò)濾,例如:
代碼如下:
'DEFAULT_FILTER' => 'strip_tags,htmlspecialchars'
代碼如下:
I('get.name'); // 等同于 htmlspecialchars(strip_tags($_GET['name']))
如果我們?cè)谑褂肐方法的時(shí)候 指定了過(guò)濾方法,那么就會(huì)忽略DEFAULT_FILTER的設(shè)置,例如:
代碼如下:
echo I('get.name','','strip_tags'); // 等同于 strip_tags($_GET['name'])
I方法的第三個(gè)參數(shù)如果傳入函數(shù)名,則表示調(diào)用該函數(shù)對(duì)變量進(jìn)行過(guò)濾并返回(在變量是數(shù)組的情況下自動(dòng)使用array_map進(jìn)行過(guò)濾處理),否則會(huì)調(diào)用內(nèi)置的filter_var方法進(jìn)行過(guò)濾處理,例如:
代碼如下:
I('post.email','',FILTER_VALIDATE_EMAIL);
表示 會(huì)對(duì)$_POST[‘email'] 進(jìn)行 格式驗(yàn)證,如果不符合要求的話,返回空字符串。
(關(guān)于更多的驗(yàn)證格式,可以參考 官方手冊(cè)的filter_var用法。)
或者可以用下面的字符標(biāo)識(shí)方式:
代碼如下:
I('post.email','','email');
可以支持的過(guò)濾名稱(chēng)必須是filter_list方法中的有效值(不同的服務(wù)器環(huán)境可能有所不同),可能支持的包括:
代碼如下:
int
boolean
float
validate_regexp
validate_url
validate_email
validate_ip
string
stripped
encoded
special_chars
unsafe_raw
url
number_int
number_float
magic_quotes
callback
在有些特殊的情況下,我們不希望進(jìn)行任何過(guò)濾,即使DEFAULT_FILTER已經(jīng)有所設(shè)置,可以使用:
代碼如下:
I('get.name','',NULL);
一旦過(guò)濾參數(shù)設(shè)置為NULL,即表示不再進(jìn)行任何的過(guò)濾。
L方法
L方法用于啟用多語(yǔ)言的情況下,設(shè)置和獲取當(dāng)前的語(yǔ)言定義。
調(diào)用格式:L(‘語(yǔ)言變量',[‘語(yǔ)言值'])
設(shè)置語(yǔ)言變量
除了使用語(yǔ)言包定義語(yǔ)言變量之外,我們可以用L方法動(dòng)態(tài)設(shè)置語(yǔ)言變量,例如:
代碼如下:
L('LANG_VAR','語(yǔ)言定義');
語(yǔ)言定義不區(qū)分大小寫(xiě),所以下面也是等效的:
代碼如下:
L('lang_var','語(yǔ)言定義');
不過(guò)規(guī)范起見(jiàn),我們建議統(tǒng)一采用大寫(xiě)定義語(yǔ)言變量。
L方法支持批量設(shè)置語(yǔ)言變量,例如:
代碼如下:
$lang['lang_var1'] = '語(yǔ)言定義1';
$lang['lang_var2'] = '語(yǔ)言定義2';
$lang['lang_var3'] = '語(yǔ)言定義3';
L($lang);
表示同時(shí)設(shè)置3個(gè)語(yǔ)言變量lang_var1 lang_var2和lang_var3。
[-more-]
獲取語(yǔ)言變量
代碼如下:
$langVar = L('LANG_VAR');
或者:
代碼如下:
$langVar = L('lang_var');
如果參數(shù)為空,表示獲取當(dāng)前定義的全部語(yǔ)言變量(包括語(yǔ)言定義文件中的):
代碼如下:
$lang = L();
或者我們也可以在模板中使用
代碼如下:
{$Think.lang.lang_var}
來(lái)輸出語(yǔ)言定義。
M方法
M方法用于實(shí)例化一個(gè)基礎(chǔ)模型類(lèi),和D方法的區(qū)別在于:
、不需要自定義模型類(lèi),減少I(mǎi)O加載,性能較好;
、實(shí)例化后只能調(diào)用基礎(chǔ)模型類(lèi)(默認(rèn)是Model類(lèi))中的方法;
、可以在實(shí)例化的時(shí)候指定表前綴、數(shù)據(jù)庫(kù)和數(shù)據(jù)庫(kù)的連接信息;
D方法的強(qiáng)大則體現(xiàn)在你封裝的自定義模型類(lèi)有多強(qiáng),不過(guò)隨著新版Think框架的基礎(chǔ)模型類(lèi)的功能越來(lái)越強(qiáng)大,M方法也比D方法越來(lái)越實(shí)用了。
M方法的調(diào)用格式:
M(‘[基礎(chǔ)模型名:]模型名','數(shù)據(jù)表前綴','數(shù)據(jù)庫(kù)連接信息')
我們來(lái)看下M方法具體有哪些用法:
、實(shí)例化基礎(chǔ)模型(Model) 類(lèi)
在沒(méi)有定義任何模型的時(shí)候,我們可以使用下面的方法實(shí)例化一個(gè)模型類(lèi)來(lái)進(jìn)行操作:
代碼如下:
//實(shí)例化User模型
$User = M('User');
//執(zhí)行其他的數(shù)據(jù)操作
$User->select();
這種方法最簡(jiǎn)單高效,因?yàn)椴恍枰x任何的模型類(lèi),所以支持跨項(xiàng)目調(diào)用。缺點(diǎn)也是因?yàn)闆](méi)有自定義的模型類(lèi),因此無(wú)法寫(xiě)入相關(guān)的業(yè)務(wù)邏輯,只能完成基本的CURD操作。
代碼如下:
$User = M('User');
其實(shí)等效于:
代碼如下:
$User = new Model('User');
表示操作think_user表。M方法和D方法一樣也有單例功能,多次調(diào)用并不會(huì)重復(fù)實(shí)例化。M方法的模型名參數(shù)在轉(zhuǎn)換成數(shù)據(jù)表的時(shí)候會(huì)自動(dòng)轉(zhuǎn)換成小寫(xiě),也就是說(shuō)Think的數(shù)據(jù)表命名規(guī)范是全小寫(xiě)的格式。
、實(shí)例化其他公共模型類(lèi)
第一種方式實(shí)例化因?yàn)闆](méi)有模型類(lèi)的定義,因此很難封裝一些額外的邏輯方法,不過(guò)大多數(shù)情況下,也許只是需要擴(kuò)展一些通用的邏輯,那么就可以嘗試下面一種方法。
代碼如下:
$User = M('CommonModel:User');
改用法其實(shí)等效于:
代碼如下:
$User = new CommonModel('User');
因?yàn)橄到y(tǒng)的模型類(lèi)都能夠自動(dòng)加載,因此我們不需要在實(shí)例化之前手動(dòng)進(jìn)行類(lèi)庫(kù)導(dǎo)入操作。模型類(lèi)CommonModel必須繼承Model。我們可以在CommonModel類(lèi)里面定義一些通用的邏輯方法,就可以省去為每個(gè)數(shù)據(jù)表定義具體的模型類(lèi),如果你的項(xiàng)目已經(jīng)有超過(guò)100個(gè)數(shù)據(jù)表了,而大多數(shù)情況都是一些基本的CURD操作的話,只是個(gè)別模型有一些復(fù)雜的業(yè)務(wù)邏輯需要封裝,那么第一種方式和第二種方式的結(jié)合是一個(gè)不錯(cuò)的選擇。
、傳入表前綴、數(shù)據(jù)庫(kù)和其他信息
M方法有三個(gè)參數(shù),第一個(gè)參數(shù)是模型名稱(chēng)(可以包括基礎(chǔ)模型類(lèi)和數(shù)據(jù)庫(kù)),第二個(gè)參數(shù)用于設(shè)置數(shù)據(jù)表的前綴(留空則取當(dāng)前項(xiàng)目配置的表前綴),第三個(gè)參數(shù)用于設(shè)置當(dāng)前使用的數(shù)據(jù)庫(kù)連接信息(留空則取當(dāng)前項(xiàng)目配置的數(shù)據(jù)庫(kù)連接信息),例如:
代碼如下:
$User = M('db2.User','think_');
表示實(shí)例化Model模型類(lèi),并操作db2數(shù)據(jù)庫(kù)中的think_user表。
如果第二個(gè)參數(shù)留空或者不傳,表示使用當(dāng)前項(xiàng)目配置中的數(shù)據(jù)表前綴,如果操作的數(shù)據(jù)表沒(méi)有表前綴,那么可以使用:
代碼如下:
$User = M('db1.User',null);
表示實(shí)例化Model模型類(lèi),并操作db1數(shù)據(jù)庫(kù)中的user表。
如果你操作的數(shù)據(jù)庫(kù)需要不同的用戶(hù)賬號(hào),可以傳入數(shù)據(jù)庫(kù)的連接信息,例如:
代碼如下:
$User = M('User','think_','mysql://user_a:1234@localhost:3306/think');
表示基礎(chǔ)模型類(lèi)用Model,然后對(duì)think_user表進(jìn)行操作,用user_a賬號(hào)進(jìn)行數(shù)據(jù)庫(kù)連接,操作數(shù)據(jù)庫(kù)是think。
第三個(gè)連接信息參數(shù)可以使用DSN配置或者數(shù)組配置,甚至可以支持配置參數(shù)。
例如,在項(xiàng)目配置文件中配置了:
代碼如下:
'DB_CONFIG'=>'mysql://user_a:1234@localhost:3306/think';
則可以使用:
代碼如下:
$User = M('User','think_','DB_CONFIG');
基礎(chǔ)模型類(lèi)和數(shù)據(jù)庫(kù)可以一起使用,例如:
代碼如下:
$User = M('CommonModel:db2.User','think_');
如果要實(shí)例化分層模型的話,利用公共模型類(lèi)的方式,我們可以使用:
代碼如下:
M('UserLogic:User');
來(lái)實(shí)例化UserLogic,雖然這樣做的意義不大,因?yàn)榭梢杂?/P>
代碼如下:
D('User','Logic');
實(shí)現(xiàn)同樣的功能。
R方法
R方法用于調(diào)用某個(gè)控制器的操作方法,是A方法的進(jìn)一步增強(qiáng)和補(bǔ)充。關(guān)于A方法的用法見(jiàn)這里。
R方法的調(diào)用格式:
R(‘[項(xiàng)目://][分組/]模塊/操作','參數(shù)','控制器層名稱(chēng)')
例如,我們定義了一個(gè)操作方法為:
代碼如下:
class UserAction extends Action {
public function detail($id){
return M('User')->find($id);
}
}
那么就可以通過(guò)R方法在其他控制器里面調(diào)用這個(gè)操作方法(一般R方法用于跨模塊調(diào)用)
代碼如下:
$data = R('User/detail',array('5'));
表示調(diào)用User控制器的detail方法(detail方法必須是public類(lèi)型),返回值就是查詢(xún)id為5的一個(gè)用戶(hù)數(shù)據(jù)。如果你要調(diào)用的操作方法是沒(méi)有任何參數(shù)的話,第二個(gè)參數(shù)則可以留空,直接使用:
代碼如下:
$data = R('User/detail');
也可以支持跨分組和項(xiàng)目調(diào)用,例如:
代碼如下:
R('Admin/User/detail',array('5'));
表示調(diào)用Admin分組下面的User控制器的detail方法。
代碼如下:
R('Admin://User/detail',array('5'));
表示調(diào)用Admin項(xiàng)目下面的User控制器的detail方法。
官方的建議是不要在同一層多太多調(diào)用,會(huì)引起邏輯的混亂,被公共調(diào)用的部分應(yīng)該封裝成單獨(dú)的接口,可以借助3.1的新特性多層控制器,單獨(dú)添加一個(gè)控制器層用于接口調(diào)用,例如,我們?cè)黾右粋€(gè)Api控制器層,
代碼如下:
class UserApi extends Action {
public function detail($id){
return M('User')->find($id);
}
}
然后,使用R方法調(diào)用
代碼如下:
$data = R('User/detail',array('5'),'Api');
也就是說(shuō),R方法的第三個(gè)參數(shù)支持指定調(diào)用的控制器層。
同時(shí),R方法調(diào)用操作方法的時(shí)候可以支持操作后綴設(shè)置C(‘ACTION_SUFFIX'),如果你設(shè)置了操作方法后綴,仍然不需要更改R方法的調(diào)用方式。
S方法
S方法還支持對(duì)當(dāng)前的緩存方式傳入緩存參數(shù),例如:
代碼如下:
S('data',$Data,3600,'File',array('length'=>10,'temp'=>RUNTIME_PATH.'temp/'));
經(jīng)測(cè)試,這樣使用 只有前三個(gè)參數(shù)有效,后面的均無(wú)效
代碼如下:
{ 'File',array('length'=>10,'temp'=>RUNTIME_PATH.'temp/')}
最終這么用:
代碼如下:
S('data1',$list,array('prefix'=>aaa','expire'=>'3600','temp'=>RUNTIME_PATH.'temp/1236'));
獲取的時(shí)候:
代碼如下:
$sdata = S('data1','',array('prefix'=>'aaa','temp'=>RUNTIME_PATH.'temp/1236'));
T方法
為了更方便的輸出模板文件,新版封裝了一個(gè)T函數(shù)用于生成模板文件名。
用法:
T([資源://][模塊@][主題/][控制器/]操作,[視圖分層])
T函數(shù)的返回值是一個(gè)完整的模板文件名,可以直接用于display和fetch方法進(jìn)行渲染輸出。
例如:
代碼如下:
T('Public/menu');
// 返回 當(dāng)前模塊/View/Public/menu.html
T('blue/Public/menu');
// 返回 當(dāng)前模塊/View/blue/Public/menu.html
T('Public/menu','Tpl');
// 返回 當(dāng)前模塊/Tpl/Public/menu.html
T('Public/menu');
// 如果TMPL_FILE_DEPR 為 _ 返回 當(dāng)前模塊/Tpl/Public_menu.html
T('Public/menu');
// 如果TMPL_TEMPLATE_SUFFIX 為.tpl 返回 當(dāng)前模塊/Tpl/Public/menu.tpl
T('Admin@Public/menu');
// 返回 Admin/View/Public/menu.html
T('Extend://Admin@Public/menu');
// 返回 Extend/Admin/View/Public/menu.html (Extend目錄取決于AUTOLOAD_NAMESPACE中的配置)
在display方法中直接使用T函數(shù):
代碼如下:
// 使用T函數(shù)輸出模板
$this->display(T('Admin@Public/menu'));
T函數(shù)可以輸出不同的視圖分層模板。
U方法
U方法用于完成對(duì)URL地址的組裝,特點(diǎn)在于可以自動(dòng)根據(jù)當(dāng)前的URL模式和設(shè)置生成對(duì)應(yīng)的URL地址,格式為:
U(‘地址','參數(shù)','偽靜態(tài)','是否跳轉(zhuǎn)','顯示域名');
在模板中使用U方法而不是固定寫(xiě)死URL地址的好處在于,一旦你的環(huán)境變化或者參數(shù)設(shè)置改變,你不需要更改模板中的任何代碼。
在模板中的調(diào)用格式需要采用 {:U('地址', '參數(shù)'…)} 的方式
U方法的用法示例:
代碼如下:
U('User/add') // 生成User模塊的add操作地址
也可以支持分組調(diào)用:
代碼如下:
U('Home/User/add') // 生成Home分組的User模塊的add操作地址
當(dāng)然,也可以只是寫(xiě)操作名,表示調(diào)用當(dāng)前模塊的
代碼如下:
U('add') // 生成當(dāng)前訪問(wèn)模塊的add操作地址
除了分組、模塊和操作名之外,我們也可以傳入一些參數(shù):
代碼如下:
U('Blog/readid=1') // 生成Blog模塊的read操作 并且id為1的URL地址
U方法的第二個(gè)參數(shù)支持傳入?yún)?shù),支持?jǐn)?shù)組和字符串兩種定義方式,如果只是字符串方式的參數(shù)可以在第一個(gè)參數(shù)中定義,下面幾種方式都是等效的:
代碼如下:
U('Blog/cate',array('cate_id'=>1,'status'=>1))
U('Blog/cate','cate_id=1&status=1')
U('Blog/catecate_id=1&status=1')
但是不允許使用下面的定義方式來(lái)傳參數(shù):
代碼如下:
U('Blog/cate/cate_id/1/status/1')
根據(jù)項(xiàng)目的不同URL設(shè)置,同樣的U方法調(diào)用可以智能地對(duì)應(yīng)產(chǎn)生不同的URL地址效果,例如針對(duì):
代碼如下:
U('Blog/readid=1')
這個(gè)定義為例。
如果當(dāng)前URL設(shè)置為普通模式的話,最后生成的URL地址是:
代碼如下:
http://serverName/index.m=Blog&a=read&id=1
如果當(dāng)前URL設(shè)置為PATHINFO模式的話,同樣的方法最后生成的URL地址是: http://serverName/index./Blog/read/id/1
如果當(dāng)前URL設(shè)置為REWRITE模式的話,同樣的方法最后生成的URL地址是: http://serverName/Blog/read/id/1
如果你同時(shí)還設(shè)置了PATHINFO分隔符的話:
代碼如下:
'URL_PATHINFO_DEPR'=>'_'
就會(huì)生成
代碼如下:
http://serverName/Blog_read_id_1
如果當(dāng)前URL設(shè)置為REWRITE模式,并且設(shè)置了偽靜態(tài)后綴為html的話,同樣的方法最后生成的URL地址是:
代碼如下:
http://serverName/Blog/read/id/1.html
如果設(shè)置了多個(gè)偽靜態(tài)支持,那么會(huì)自動(dòng)取第一個(gè)偽靜態(tài)后綴添加到URL地址后面,當(dāng)然你也可以手動(dòng)在U方法里面指定要生成的偽靜態(tài)后綴,例如:
代碼如下:
U('Blog/read','id=1','xml')
就會(huì)生成
代碼如下:
http://serverName/Blog/read/id/1.xml
U方法還可以支持路由,如果我們定義了一個(gè)路由規(guī)則為:
代碼如下:
'news/:id\d'=>'News/read'
那么可以使用
代碼如下:
U('/news/1')
最終生成的URL地址是:
代碼如下:
http://serverName/index./news/1
如果你的應(yīng)用涉及到多個(gè)子域名的操作地址,那么也可以在U方法里面指定需要生成地址的域名,例如:
代碼如下:
U('Blog/read@blog.think.cn','id=1');
@后面?zhèn)魅胄枰付ǖ挠蛎纯伞?/P>
此外,U方法的第5個(gè)參數(shù)如果設(shè)置為true,表示自動(dòng)識(shí)別當(dāng)前的域名,并且會(huì)自動(dòng)根據(jù)子域名部署設(shè)置APP_SUB_DOMAIN_DEPLOY和APP_SUB_DOMAIN_RULES自動(dòng)匹配生成當(dāng)前地址的子域名。
如果開(kāi)啟了URL_CASE_INSENSITIVE,則會(huì)統(tǒng)一生成小寫(xiě)的URL地址。