ThinkPHP採用單一入口模式訪問應用,對應用的全部請求都定向到應用的入口文件,系統會從URL參數中解析當前請求的模塊、控制器和操做,下面是一個標準的URL訪問格式:
http://serverName/index.php/模塊/控制器/操做javascript
若是咱們直接訪問入口文件的話,因爲URL中沒有模塊、控制器和操做,所以系統會訪問默認模塊(Home)下面的默認控制器(Index)的默認操做(index),所以下面的訪問是等效的:php
http://serverName/index.php
http://serverName/index.php/Home/Index/index
複製代碼
這種URL模式就是系統默認的PATHINFO模式,不一樣的URL模式獲取模塊和操做的方法不一樣,ThinkPHP支持的URL模式有四種:普通模式、PATHINFO、REWRITE和兼容模式。html
這裏用到了M函數,是ThinkPHP內置的實例化模型的方法,並且用M方法實例化模型不須要建立對應的模型類,你能夠理解爲M方法是直接在操做底層的Model類,而Model類具有基本的CURD操做方法。java
M('Data') 實例化後,就能夠對think_data數據表(think_ 是咱們在項目配置文件中定義的數據表前綴)進行操做(包括CURD)了,M函數的用法還有不少,咱們之後會深刻了解。linux
CURD是一個數據庫技術中的縮寫詞,通常的項目開發的各類參數的基本功能都是CURD。它表明建立(Create)、更新(Update)、讀取(Read)和刪除(Delete)操做。CURD 定義了用於處理數據的基本原子操做。之因此將CURD 提高到一個技術難題的高度是由於完成一個涉及在多個數據庫系統中進行CURD操做的彙總相關的活動,其性能可能會隨數據關係的變化而有很是大的差別。ajax
CURD在具體的應用中並不是必定使用create、update 、read和delete字樣的方法,可是他們完成的功能是一致的正則表達式
咱們並無在控制器裏面定義add操做方法,可是很顯然,訪問是正常的。由於ThinkPHP在沒有找到對應操做方法的狀況下,會檢查是否存在對應的模板文件,因爲咱們有對應的add模板文件,因此控制器就直接渲染該模板文件輸出了。因此說對於沒有任何實際邏輯的操做方法,咱們只須要直接定義對應的模板文件就好了。sql
在insert操做方法中用了D函數,和M函數不一樣,D函數須要有對應的模型類,下面咱們就來建立模型類。thinkphp
若是你的數據徹底是內部操做寫入而不是經過表單的話(也就是說能夠充分信任數據的安全),那麼能夠直接使用add方法,如:數據庫
$Form = D('Form');
$data['title'] = 'ThinkPHP';
$data['content'] = '表單內容';
$Form->add($data);
也能夠支持對象方式操做:
$Form = D('Form');
$Form->title = 'ThinkPHP';
$Form->content = '表單內容';
$Form->add();
對象方式操做的時候,add方法無需傳入數據,會自動識別當前的數據對象賦值。
這裏之因此用M方法而沒有用D方法,是由於find方法是基礎模型類Model中的方法,因此沒有必要浪費開銷去實例化FormModel類(即便已經定義了FormModel類)。咱們一般採用find方法讀取某個數據
若是你只須要查詢某個字段的值,還可使用getField方法,
例如:
$Form = M("Form");
// 獲取標題
$title = $Form->where('id=3')->getField('title');
上面的用法表示獲取id值爲3的數據的title字段值。其實getField方法有不少用法,可是獲取某個字段的值是getField方法最常規的用法。
查詢操做是最經常使用的操做,尤爲是涉及到複雜的查詢條件,咱們會在查詢語言一章對查詢進行更加詳細的講解。
數據的更新操做在ThinkPHP使用save方法,能夠看到,咱們一樣可使用create方法建立表單提交的數據,而save方法則會自動把當前的數據對象更新到數據庫,而更新的條件其實就是表的主鍵,這就是咱們在編輯頁面要把主鍵的值做爲隱藏字段一塊兒提交的緣由。
有些時候,咱們只須要修改某個字段的值,就可使用setField方法,而不須要每次都調用save方法。
咱們掌握了基本的數據CURD方法,但更多的狀況下面,因爲業務邏輯的差別,CURD操做每每不是那麼簡單,尤爲是複雜的業務邏輯下面,這也是ActiveRecord模式的不足之處。ThinkPHP的查詢語言配合連貫操做能夠很好解決複雜的業務邏輯需求,本篇咱們就首先來深刻了解下框架的查詢語言。
介紹
ThinkPHP內置了很是靈活的查詢方法,能夠快速的進行數據查詢操做,查詢條件能夠用於讀取、更新和刪除等操做,主要涉及到where方法等連貫操做便可,不管是採用什麼數據庫,你幾乎採用同樣的查詢方法(個別數據庫例如Mongo在表達式查詢方面會有所差別),系統幫你解決了不一樣數據庫的差別性,所以咱們把框架的這一查詢方式稱之爲查詢語言。查詢語言也是ThinkPHP框架的ORM亮點,讓查詢操做更加簡單易懂
1、使用字符串做爲查詢條件
$User = M("User"); // 實例化User對象
$User->where('type=1 AND status=1')->select();
2、使用數組做爲查詢條件(把多個條件複製給數組 最後傳入條件數組)
$User = M("User"); // 實例化User對象
$condition['name'] = 'thinkphp';
$condition['status'] = 1;
// 把查詢條件傳入查詢方法
經過使用 _logic 定義查詢邏輯:$condition['_logic'] = 'OR'; 還有and
$User->where($condition)->select();
3、使用對象方式來查詢
$User = M("User"); // 實例化User對象
// 定義查詢條件
$condition = new stdClass();
$condition->name = 'thinkphp';
$condition->status= 1;
$User->where($condition)->select();
使用對象方式查詢和使用數組查詢的效果是相同的,而且是能夠互換的,大多數狀況下,咱們建議採用數組方式更加高效。
表達式查詢
上面的查詢條件僅僅是一個簡單的相等判斷,可使用查詢表達式支持更多的SQL查詢語法,也是ThinkPHP查詢語言的精髓,查詢表達式的使用格式:
$map['字段名'] = array('表達式','查詢條件');
表達式 含義
EQ 等於(=)
NEQ 不等於(<>)
GT 大於(>)
EGT 大於等於(>=)
LT 小於(<)
ELT 小於等於(<=)
LIKE 模糊查詢
[NOT] BETWEEN (不在)區間查詢
[NOT] IN (不在)IN 查詢
EXP 表達式查詢,支持SQL語法
示例以下:
EQ :等於(=)
例如:
$map['id'] = array('eq',100);
和下面的查詢等效
$map['id'] = 100;
表示的查詢條件就是id = 100
NEQ: 不等於(<>)
例如:
$map['id'] = array('neq',100);
表示的查詢條件就是 id <> 100
GT:大於(>)
例如:
$map['id'] = array('gt',100);
表示的查詢條件就是 id > 100
快捷查詢
採用快捷查詢方式,能夠進一步簡化查詢條件的寫法,例如:
1、實現不一樣字段相同的查詢條件
$User = M("User"); // 實例化User對象
$map['name|title'] = 'thinkphp';
// 把查詢條件傳入查詢方法
$User->where($map)->select();
查詢條件就變成
name= 'thinkphp' OR title = 'thinkphp'
2、實現不一樣字段不一樣的查詢條件
$User = M("User"); // 實例化User對象
$map['status&title'] =array('1','thinkphp','_multi'=>true);
// 把查詢條件傳入查詢方法
$User->where($map)->select();
'_multi'=>true必須加在數組的最後,表示當前是多條件匹配,這樣查詢條件就變成
status= 1 AND title = 'thinkphp'
,查詢字段支持更多的,例如:
$map['status&score&title'] =array('1',array('gt','0'),'thinkphp','_multi'=>true);
查詢條件就變成
status= 1 AND score >0 AND title = 'thinkphp'
注意:快捷查詢方式中「|」和「&」不能同時使用。
區間查詢
ThinkPHP支持對某個字段的區間查詢,例如:
$map['id'] = array(array('gt',1),array('lt',10),'and') ;
獲得的查詢條件是:
(`id` > 1) AND (`id` < 10)
最後一個能夠是AND、 OR或者 XOR運算符,若是不寫,默認是AND運算。
區間查詢的條件能夠支持普通查詢的全部表達式,也就是說相似LIKE、GT和EXP這樣的表達式均可以支持。另外區間查詢還能夠支持更多的條件,只要是針對一個字段的條件均可以寫到一塊兒,例如:
$map['name'] = array(array('like','%a%'), array('like','%b%'), array('like','%c%'), 'ThinkPHP','or');
最後的查詢條件是:
(`name` LIKE '%a%') OR (`name` LIKE '%b%') OR (`name` LIKE '%c%') OR (`name` = 'ThinkPHP')
組合查詢
組合查詢的主體仍是採用數組方式查詢,只是加入了一些特殊的查詢支持,包括字符串模式查詢(_string)、複合查詢(_complex)、請求字符串查詢(_query),混合查詢中的特殊查詢每次查詢只能定義一個,因爲採用數組的索引方式,索引相同的特殊查詢會被覆蓋。
1、字符串模式查詢(採用_string 做爲查詢條件)
數組條件還能夠和字符串條件混合使用,例如:
$User = M("User"); // 實例化User對象
$map['id'] = array('neq',1);
$map['name'] = 'ok';
$map['_string'] = 'status=1 AND score>10';
$User->where($map)->select();
最後獲得的查詢條件就成了:
( `id` != 1 ) AND ( `name` = 'ok' ) AND ( status=1 AND score>10 )
2、請求字符串查詢方式
請求字符串查詢是一種相似於URL傳參的方式,能夠支持簡單的條件相等判斷。
$map['id'] = array('gt','100');
$map['_query'] = 'status=1&score=100&_logic=or';
獲得的查詢條件是:
`id`>100 AND (`status` = '1' OR `score` = '100')
3、複合查詢
複合查詢至關於封裝了一個新的查詢條件,而後併入原來的查詢條件之中,因此能夠完成比較複雜的查詢條件組裝。
例如:
$where['name'] = array('like', '%thinkphp%');
$where['title'] = array('like','%thinkphp%');
$where['_logic'] = 'or';
$map['_complex'] = $where;
$map['id'] = array('gt',1);
查詢條件是
( id > 1) AND ( ( name like '%thinkphp%') OR ( title like '%thinkphp%') )
複合查詢使用了_complex做爲子查詢條件來定義,配合以前的查詢方式,能夠很是靈活的制定更加複雜的查詢條件。
不少查詢方式能夠相互轉換,例如上面的查詢條件能夠改爲:
$where['id'] = array('gt',1);
$where['_string'] = ' (name like "%thinkphp%") OR ( title like "%thinkphp") ';
複製代碼
最後生成的SQL語句是一致的。
統計查詢
在應用中咱們常常會用到一些統計數據,例如當前全部(或者知足某些條件)的用戶數、全部用戶的最大積分、用戶的平均成績等等,ThinkPHP爲這些統計操做提供了一系列的內置方法,包括:
方法 說明
Count 統計數量,參數是要統計的字段名(可選)
Max 獲取最大值,參數是要統計的字段名(必須)
Min 獲取最小值,參數是要統計的字段名(必須)
Avg 獲取平均值,參數是要統計的字段名(必須)
Sum 獲取總分,參數是要統計的字段名(必須)
用法示例:
$User = M("User"); // 實例化User對象
// 獲取用戶數:
$userCount = $User->count();
// 或者根據字段統計:
$userCount = $User->count("id");
// 獲取用戶的最大積分:
$maxScore = $User->max('score');
// 獲取積分大於0的用戶的最小積分:
$minScore = $User->where('score>0')->min('score');
// 獲取用戶的平均積分:
$avgScore = $User->avg('score');
// 統計用戶的總成績:
$sumScore = $User->sum('score');
複製代碼
而且全部的統計查詢均支持連貫操做的使用。
SQL查詢
ThinkPHP內置的ORM和ActiveRecord模式實現了方便的數據存取操做,並且新版增長的連貫操做功能更是讓這個數據操做更加清晰,可是ThinkPHP仍然保留了原生的SQL查詢和執行操做支持,爲了知足複雜查詢的須要和一些特殊的數據操做,SQL查詢的返回值由於是直接返回的Db類的查詢結果,沒有作任何的處理。主要包括下面兩個方法:
一、query方法
query 執行SQL查詢操做
用法 query($sql,$parse=false)
參數 sql(必須):要查詢的SQL語句 parse(可選):是否須要解析SQL
返回值 若是數據非法或者查詢錯誤則返回false,不然返回查詢結果數據集(同select方法)
使用示例:
$Model = new Model() // 實例化一個model對象 沒有對應任何數據表
$Model->query("select * from think_user where status=1");
若是你當前採用了分佈式數據庫,而且設置了讀寫分離的話,query方法始終是在讀服務器執行,所以query方法對應的都是讀操做,而無論你的SQL語句是什麼。
二、execute方法
execute 用於更新和寫入數據的sql操做
用法 execute($sql,$parse=false)
參數 sql(必須):要執行的SQL語句 parse(可選):是否須要解析SQL
返回值 若是數據非法或者查詢錯誤則返回false ,不然返回影響的記錄數
使用示例:
$Model = new Model() // 實例化一個model對象 沒有對應任何數據表
$Model->execute("update think_user set name='thinkPHP' where status=1");
複製代碼
若是你當前採用了分佈式數據庫,而且設置了讀寫分離的話,execute方法始終是在寫服務器執行,所以execute方法對應的都是寫操做,而無論你的SQL語句是什麼。
動態查詢
藉助PHP5語言的特性,ThinkPHP實現了動態查詢,核心模型的動態查詢方法包括下面幾種:
方法名 說明 舉例
getBy 根據字段的值查詢數據 例如,getByName,getByEmail
getFieldBy 根據字段查詢並返回某個字段的值 例如,getFieldByName
1、getBy動態查詢
該查詢方式針對數據表的字段進行查詢。例如,User對象擁有id,name,email,address 等屬性,那麼咱們就可使用下面的查詢方法來直接根據某個屬性來查詢符合條件的記錄。
$user = $User->getByName('liu21st');
$user = $User->getByEmail('liu21st@gmail.com');
$user = $User->getByAddress('中國深圳');
暫時不支持多數據字段的動態查詢方法,請使用find方法和select方法進行查詢。
2、getFieldBy動態查詢
針對某個字段查詢並返回某個字段的值,例如
$userId = $User->getFieldByName('liu21st','id');
表示根據用戶的name獲取用戶的id值。
子查詢
子查詢有兩種使用方式:
一、使用select方法
當select方法的參數爲false的時候,表示不進行查詢只是返回構建SQL,例如:
// 首先構造子查詢SQL
$subQuery = $model->field('id,name')->table('tablename')->group('field')->where($where)->order('status')->select(false);
當select方法傳入false參數的時候,表示不執行當前查詢,而只是生成查詢SQL。
二、使用buildSql方法
$subQuery = $model->field('id,name')->table('tablename')->group('field')->where($where)->order('status')->buildSql();
調用buildSql方法後不會進行實際的查詢操做,而只是生成該次查詢的SQL語句(爲了不混淆,會在SQL兩邊加上括號),而後咱們直接在後續的查詢中直接調用。
// 利用子查詢進行查詢
$model->table($subQuery.' a')->where()->order()->select()
構造的子查詢SQL可用於ThinkPHP的連貫操做方法,例如table where等。
連貫操做能夠有效的提升數據存取的代碼清晰度和開發效率,而且支持全部的CURD操做,也是ThinkPHP的ORM中的一個亮點。使用也比較簡單, 假如咱們如今要查詢一個User表的知足狀態爲1的前10條記錄,並但願按照用戶的建立時間排序 ,代碼以下:
$User->where('status=1')->order('create_time')->limit(10)->select();
複製代碼
這裏的where、order和limit方法就稱之爲連貫操做方法,除了select方法必須放到最後一個外(由於select方法並非連貫操做方法),連貫操做的方法調用順序沒有前後
連貫操做僅在當次查詢或者操做有效,完成後會自動清空連貫操做的全部傳值(有個別特殊的連貫操做會記錄當前的傳值,如cache連貫操做)。簡而言之,連貫操做的結果不會帶入之後的查詢。
系統支持的連貫操做方法有:
方法 做用 支持的參數類型
where* 用於查詢或者更新條件的定義 字符串、數組和對象
table 用於定義要操做的數據表名稱 字符串和數組
alias 用於給當前數據表定義別名 字符串
data 用於新增或者更新數據以前的數據對象賦值 數組和對象
field 用於定義要查詢的字段(支持字段排除) 字符串和數組
order 用於對結果排序 字符串和數組
limit 用於限制查詢結果數量 字符串和數字
page 用於查詢分頁(內部會轉換成limit) 字符串和數字
group 用於對查詢的group支持 字符串
having 用於對查詢的having支持 字符串
join* 用於對查詢的join支持 字符串和數組
union* 用於對查詢的union支持 字符串、數組和對象
distinct 用於查詢的distinct支持 布爾值
lock 用於數據庫的鎖機制 布爾值
cache 用於查詢緩存 支持多個參數(之後在緩存部分再詳細描述)
relation 用於關聯查詢(須要關聯模型擴展支持) 字符串
validate 用於數據自動驗證 數組
auto 用於數據自動完成 數組
filter 用於數據過濾 字符串
scope* 用於命名範圍 字符串、數組
bind* 用於數據綁定操做 數組或多個參數
token 用於令牌驗證 布爾值
comment 用於SQL註釋 字符串
index 用於數據集的強制索引 字符串
strict 用於數據入庫的嚴格檢測 布爾值
全部的連貫操做都返回當前的模型實例對象,其中帶*標識的表示支持屢次調用
I方法是ThinkPHP用於更加方便和安全的獲取系統輸入變量,能夠用於任何地方,用法格式以下:
I('變量類型.變量名/修飾符',['默認值'],['過濾方法'],['額外數據源'])
變量類型是指請求方式或者輸入類型,包括:
變量類型 含義
get 獲取GET參數
post 獲取POST參數
param 自動判斷請求類型獲取GET、POST或者PUT參數
request 獲取REQUEST 參數
put 獲取PUT 參數
session 獲取 $_SESSION 參數
cookie 獲取 $_COOKIE 參數
server 獲取 $_SERVER 參數
globals 獲取 $GLOBALS參數
path 獲取 PATHINFO模式的URL參數
data 獲取 其餘類型的參數,須要配合額外數據源參數
注意:變量類型不區分大小寫。
變量名則嚴格區分大小寫。
默認值和過濾方法均屬於可選參數。
咱們以GET變量類型爲例,說明下I方法的使用:
echo I('get.id'); // 至關於 $_GET['id']
echo I('get.name'); // 至關於 $_GET['name']
支持默認值:
echo I('get.id',0); // 若是不存在$_GET['id'] 則返回0
echo I('get.name',''); // 若是不存在$_GET['name'] 則返回空字符串
採用方法過濾:
// 採用htmlspecialchars方法對$_GET['name'] 進行過濾,若是不存在則返回空字符串
echo I('get.name','','htmlspecialchars');
支持直接獲取整個變量類型,例如:
// 獲取整個$_GET 數組
I('get.');
用一樣的方式,咱們能夠獲取post或者其餘輸入類型的變量,例如:
I('post.name','','htmlspecialchars'); // 採用htmlspecialchars方法對$_POST['name'] 進行過濾,若是不存在則返回空字符串
I('session.user_id',0); // 獲取$_SESSION['user_id'] 若是不存在則默認爲0
I('cookie.'); // 獲取整個 $_COOKIE 數組
I('server.REQUEST_METHOD'); // 獲取 $_SERVER['REQUEST_METHOD']
param變量類型是框架特有的支持自動判斷當前請求類型的變量獲取方式,例如:
echo I('param.id');
若是當前請求類型是GET,那麼等效於 $_GET['id'],若是當前請求類型是POST或者PUT,那麼至關於獲取 $_POST['id'] 或者 PUT參數id。
因爲param類型是I函數默認獲取的變量類型,所以事實上param變量類型的寫法能夠簡化爲:
I('id'); // 等同於 I('param.id')
I('name'); // 等同於 I('param.name')
path類型變量能夠用於獲取PATHINFO方式的URL參數(必須是PATHINFO模式參數有效,不管是GET仍是POST方式都有效)
I方法的全部獲取變量若是沒有設置過濾方法的話都會進行htmlspecialchars過濾,那麼:// 等同於
htmlspecialchars($_GET['name'])
I('get.name');
,該參數也能夠設置支持多個過濾,例如:
'DEFAULT_FILTER' => 'strip_tags,htmlspecialchars'
設置後,咱們在使用:
// 等同於 htmlspecialchars(strip_tags($_GET['name']))
I('get.name');
若是咱們在使用I方法的時候 指定了過濾方法,那麼就會忽略DEFAULT_FILTER的設置,例如:
// 等同於 strip_tags($_GET['name'])
echo I('get.name','','strip_tags');
過濾名稱必須是filter_list方法中的有效值(不一樣的服務器環境可能有所不一樣),可能支持的包括:
int
boolean
float
validate_regexp
validate_url
validate_email
validate_ip
string
stripped
encoded
special_chars
unsafe_raw
email
url
number_int
number_float
magic_quotes
callback
也能夠支持正則匹配過濾,例如:
// 採用正則表達式進行變量過濾
I('get.name','','/^[A-Za-z]+$/');
I('get.id',0,'/^\d+$/');
若是正則匹配不經過的話,則返回默認值。
變量修飾符
I函數支持對變量使用修飾符功能,能夠更好的過濾變量。
用法以下:
I('變量類型.變量名/修飾符');
例如:
I('get.id/d');
I('post.name/s');
I('post.ids/a');
可使用的修飾符包括:
修飾符 做用
s 強制轉換爲字符串類型
d 強制轉換爲整形類型
b 強制轉換爲布爾類型
a 強制轉換爲數組類型
f 強制轉換爲浮點類型
模板定義
每一個模塊的模板文件是獨立的,爲了對模板文件更加有效的管理,ThinkPHP對模板文件進行目錄劃分,默認的模板文件定義規則是:
視圖目錄/[模板主題/]控制器名/操做名+模板後綴
默認的視圖目錄是模塊的View目錄(模塊能夠有多個視圖文件目錄,這取決於你的應用須要),框架的默認視圖文件後綴是.html。
大多數狀況下你不須要主題功能,所以新版模板主題默認是空(表示不啓用模板主題功能)。
通常狀況下,模板文件都在模塊的視圖目錄下面,而且是以模塊下面的控制器名爲目錄,而後是每一個控制器的具體操做模板文件,例如:
User控制器的add操做對應的模板文件就應該是:./Application/Home/View/User/add.html
若是你的默認視圖層不是View,例如:
// 設置默認的視圖層名稱
'DEFAULT_V_LAYER' => 'Template',
那麼,對應的模板文件就變成了:./Application/Home/Template/User/add.html。
模板文件的默認後綴的狀況是.html,也能夠經過 TMPL_TEMPLATE_SUFFIX 來配置成其餘的。例如,咱們能夠配置:
'TMPL_TEMPLATE_SUFFIX'=>'.tpl'
定義後,User控制器的add操做 對應的模板文件就變成是: ./Application/Home/View/User/add.tpl
若是以爲目錄結構太深,能夠經過設置 TMPL_FILE_DEPR 參數來配置簡化模板的目錄層次,例如設置:
'TMPL_FILE_DEPR'=>'_'
默認的模板文件就變成了:./Application/Home/View/User_add.html
渲染模板輸出最經常使用的是使用display方法,調用格式:
display('[模板文件]'[,'字符編碼'][,'輸出類型'])
模板文件的寫法支持下面幾種:
用法 描述
不帶任何參數 自動定位當前操做的模板文件
[模塊@][控制器:][操做] 經常使用寫法,支持跨模塊 模板主題能夠和theme方法配合
完整的模板文件名 直接使用完整的模板文件名(包括模板後綴)
下面是一個最典型的用法,不帶任何參數:
// 不帶任何參數 自動定位當前操做的模板文件
$this->display();
表示系統會按照默認規則自動定位模板文件,其規則是:
若是當前沒有啓用模板主題則定位到:當前模塊/默認視圖目錄/當前控制器/當前操做.html ;
若是有啓用模板主題則定位到:當前模塊/默認視圖目錄/當前主題/當前控制器/當前操做.html;
若是有更改TMPL_FILE_DEPR設置(假設 'TMPL_FILE_DEPR'=>'_')的話,則上面的自動定位規則變成: 當前模塊/默認視圖目錄/當前控制器_當前操做.html 和 當前模塊/默認視圖目錄/當前主題/當前控制器_當前操做.html。
因此一般display方法無需帶任何參數便可輸出對應的模板,這是模板輸出的最簡單的用法。
一般默認的視圖目錄是View
若是沒有按照模板定義規則來定義模板文件(或者須要調用其餘控制器下面的某個模板),可使用:
// 指定模板輸出
// 表示調用當前控制器下面的edit模板
$this->display('edit');
或者指定控制器
// 表示調用Member控制器下面的read模板
$this->display('Member:read');
若是咱們使用了模板主題功能,那麼也能夠支持跨主題調用,使用:
// 調用blue主題下面的User控制器的edit模板
$this->theme('blue')->display('User:edit');
渲染輸出不須要寫模板文件的路徑和後綴,確切地說,這裏面的控制器和操做並不必定須要有實際對應的控制器和操做,只是一個目錄名稱和文件名稱而已,例如,你的項目裏面可能根本沒有Public控制器,更沒有Public控制器的menu操做,可是同樣可使用
$this->display('Public:menu');
輸出這個模板文件。
display方法支持在渲染輸出的時候指定輸出編碼和類型,例如,能夠指定編碼和類型:
// 輸出XML頁面類型(配合你的應用需求能夠輸出不少類型)
$this->display('read', 'utf-8', 'text/xml');
若是須要獲取渲染模板的輸出內容而不是直接輸出,可使用fetch方法。
fetch方法的用法除了不須要指定輸出編碼和類型外其它和display基本一致,格式:
fetch('模板文件')
模板文件的調用方法和display方法徹底同樣,區別就在於fetch方法渲染後不是直接輸出,而是返回渲染後的內容,例如:
$content = $this->fetch('Member:edit');
使用fetch方法獲取渲染內容後,你能夠進行過濾和替換等操做,或者用於對輸出的複雜需求。
渲染內容
若是你沒有定義任何模板文件,或者把模板內容存儲到數據庫中的話,你就須要使用show方法來渲染輸出了,show方法的調用格式:
show('渲染內容'[,'字符編碼'][,'輸出類型'])
例如,
$this->show($content);
// 也能夠指定編碼和類型
$this->show($content, 'utf-8', 'text/xml');
注意:show方法中的內容也能夠支持模板解析。
模板賦值
若是要在模板中輸出變量,必須在在控制器中把變量傳遞給模板,系統提供了assign方法對模板變量賦值,不管何種變量類型都統一使用assign賦值。
$this->assign('name',$value);
assign方法必須在display和show方法以前調用,而且系統只會輸出設定的變量,其它變量不會輸出(系統變量例外),必定程度上保證了變量的安全性。
系統變量能夠經過特殊的標籤輸出,無需賦值模板變量
賦值後,就能夠在模板文件中輸出變量了,若是使用的是內置模板的話,就能夠這樣輸出:
{$name}
若是要同時輸出多個模板變量,可使用下面的方式:
$array['name'] = 'thinkphp';
$array['email'] = 'liu21st@gmail.com';
$array['phone'] = '12335678';
$this->assign($array);
這樣,就能夠在模板文件中同時輸出name、email和phone三個變量。
模板變量的輸出根據不一樣的模板引擎有不一樣的方法,咱們在後面會專門講解內置模板引擎的用法。若是你使用的是PHP自己做爲模板引擎的話 ,就能夠直接在模板文件裏面輸出了:
<?php echo $name.'['.$email.''.$phone.']';?>
若是採用內置的模板引擎,可使用:
{$name} [ {$email} {$phone} ]
輸出一樣的內容。
變量輸出(這裏主要是指標量類型的輸出)的方法很簡單,例如,在控制器中咱們給模板變量賦值:
$name = 'ThinkPHP';
$this->assign('name',$name);
$this->display();
而後就能夠在模板中使用:
Hello,{$name}!
模板編譯後的結果就是:
Hello,<?php echo($name);?>!
這樣,運行的時候就會在模板中顯示:
Hello,ThinkPHP!
注意模板標籤的{和$之間不能有任何的空格,不然標籤無效。
因此,下面的標籤
Hello,{ $name}!
將不會正常輸出name變量,而是直接保持不變輸出:
Hello,{ $name}!
模板中咱們能夠用下面的方式輸出:
Name:{$data.name}
Email:{$data.email}
或者用下面的方式也是有效:
Name:{$data['name']}
Email:{$data['email']}
若是data變量是一個對象(而且包含有name和email兩個屬性),那麼能夠用下面的方式輸出:
Name:{$data:name}
Email:{$data:email}
或者
Name:{$data->name}
Email:{$data->email}
系統變量
普通的模板變量須要首先賦值後才能在模板中輸出,可是系統變量則不須要,能夠直接在模板中輸出,系統變量的輸出一般以{$Think 打頭,例如:
{$Think.server.script_name} // 輸出$_SERVER['SCRIPT_NAME']變量
{$Think.session.user_id} // 輸出$_SESSION['user_id']變量
{$Think.get.pageNumber} // 輸出$_GET['pageNumber']變量
{$Think.cookie.name} // 輸出$_COOKIE['name']變量
支持輸出$_SERVER、$_ENV、 $_POST、 $_GET、 $_REQUEST、$_SESSION和 $_COOKIE變量。
還能夠輸出常量
{$Think.const.MODULE_NAME}
或者直接使用
{$Think.MODULE_NAME}
使用函數
咱們每每須要對模板輸出變量使用函數,可使用:
{$data.name|md5}
編譯後的結果是:
<?php echo (md5($data['name'])); ?>
若是函數有多個參數須要調用,則使用:
{$create_time|date="y-m-d",###}
表示date函數傳入兩個參數,每一個參數用逗號分割,這裏第一個參數是y-m-d,第二個參數是前面要輸出的create_time變量,由於該變量是第二個參數,所以須要用###標識變量位置,編譯後的結果是:
<?php echo (date("y-m-d",$create_time)); ?>
若是前面輸出的變量在後面定義的函數的第一個參數,則能夠直接使用:
{$data.name|substr=0,3}
表示輸出
<?php echo (substr($data['name'],0,3)); ?>
雖然也可使用:
{$data.name|substr=###,0,3}
但徹底沒用這個必要。
還能夠支持多個函數過濾,多個函數之間用「|」分割便可,例如:
{$name|md5|strtoupper|substr=0,3}
編譯後的結果是:
<?php echo (substr(strtoupper(md5($name)),0,3)); ?>
函數會按照從左到右的順序依次調用。
若是你以爲這樣寫起來比較麻煩,也能夠直接這樣寫:
{:substr(strtoupper(md5($name)),0,3)}
默認值
咱們能夠給變量輸出提供默認值,例如:
{$user.nickname|default="這傢伙很懶,什麼也沒留下"}
對系統變量依然能夠支持默認值輸出,例如:
{$Think.get.name|default="名稱爲空"}
默認值和函數能夠同時使用,例如:
{$Think.get.name|getName|default="名稱爲空"}
使用運算符
咱們能夠對模板輸出使用運算符,包括對「+」「 –」 「*」 「/」和「%」的支持。
例如:
運算符 使用示例
+ {$a+$b}
- {$a-$b}
* {$a*$b}
/ {$a/$b}
% {$a%$b}
++ {$a++} 或 {++$a}
-- {$a--} 或 {--$a}
綜合運算 {$a+$b*10+$c}
在使用運算符的時候,再也不支持點語法和常規的函數用法,例如:
{$user.score+10} //錯誤的
{$user['score']+10} //正確的
{$user['score']*$user['level']} //正確的
{$user['score']|myFun*10} //錯誤的
{$user['score']+myFun($user['level'])} //正確的
模板能夠支持三元運算符,例如:
{$status?'正常':'錯誤'}
{$info['status']?$info['msg']:$info['error']}
三元運算符中暫時不支持點語法,所以下面的寫法是錯誤的:
{$info.status?$info.msg:$info.error}
循環輸出
循環輸出主要是使用volist和foreach標籤輸出。
VOLIST
volist標籤一般用於查詢數據集(select方法)的結果輸出,一般模型的select方法返回的結果是一個二維數組,能夠直接使用volist標籤進行輸出。
在控制器中首先對模版賦值:
$User = M('User');
$list = $User->limit(10)->select();
$this->assign('list',$list);
在模版定義以下,循環輸出用戶的編號和姓名:
<volist name="list" id="vo">
{$vo.id}:{$vo.name}<br/>
</volist>
Volist標籤的name屬性表示模板賦值的變量名稱,所以不可隨意在模板文件中改變。id表示當前的循環變量,能夠隨意指定,但確保不要和name屬性衝突,例如:
<volist name="list" id="data">
{$data.id}:{$data.name}<br/>
</volist>
支持輸出查詢結果中的部分數據,例如輸出其中的第5~15條記錄
<volist name="list" id="vo" offset="5" length='10'>
{$vo.name}
</volist>
輸出偶數記錄
<volist name="list" id="vo" mod="2" >
<eq name="mod" value="1">{$vo.name}</eq>
</volist>
Mod屬性還用於控制必定記錄的換行,例如:
<volist name="list" id="vo" mod="5" >
{$vo.name}
<eq name="mod" value="4"><br/></eq>
</volist>
爲空的時候輸出提示:
<volist name="list" id="vo" empty="暫時沒有數據" >
{$vo.id}|{$vo.name}
</volist>
empty屬性不支持直接傳入html語法,但能夠支持變量輸出,例如:
$this->assign('empty','<span class="empty">沒有數據</span>');
$this->assign('list',$list);
而後在模板中使用:
<volist name="list" id="vo" empty="$empty" >
{$vo.id}|{$vo.name}
</volist>
模板中能夠直接使用函數設定數據集,而不須要在控制器中給模板變量賦值傳入數據集變量,如:
<volist name=":fun('arg')" id="vo">
{$vo.name}
</volist>
FOREACH
除了volist標籤以外,還可使用foreach標籤,foreach標籤相似與volist標籤,只是更加簡單,沒有太多額外的屬性,例如:
<foreach name="list" item="vo">
{$vo.id}:{$vo.name}
</foreach>
name表示數據源 item表示循環變量。
foreach標籤還能夠輸出一維數組,例如:
<foreach name="list" item="vo" >
{$key}|{$vo}
</foreach>
<switch name="User.level">
<case value="1">value1</case>
<case value="2">value2</case>
<default />default
</switch>
對於case的value屬性能夠支持多個條件的判斷,使用」|」進行分割,例如:
<switch name="Think.get.type">
<case value="gif|png|jpg">圖像格式</case>
<default />其餘格式
</switch>
表示若是$_GET["type"] 是gif、png或者jpg的話,就判斷爲圖像格式。
Case標籤還有一個break屬性,表示是否須要break,默認是會自動添加break,若是不要break,可使用:
<switch name="Think.get.userId|abs">
<case value="1" break="0">admin</case>
<case value="2">admin</case>
<default />default
</switch>
也能夠對case的value屬性使用變量,例如:
<switch name="User.userId">
<case value="$adminId">admin</case>
<case value="$memberId">member</case>
<default />default
</switch>
要求name變量的值等於value就輸出,可使用:
<eq name="name" value="value">value</eq>
能夠支持和else標籤混合使用:
<eq name="name" value="value">
相等
<else/>
不相等
</eq>
範圍判斷標籤
範圍判斷標籤包括in、notin、between和notbetween四個標籤,都用於判斷變量是否中某個範圍。
IN和NOTIN
用法:
假設咱們中控制器中給id賦值爲1:
$id = 1;
$this->assign('id',$id);
咱們可使用in標籤來判斷模板變量是否在某個範圍內,例如:
<in name="id" value="1,2,3">
id在範圍內
</in>
最後會輸出:id在範圍內。
若是判斷不在某個範圍內,可使用:
<notin name="id" value="1,2,3">
id不在範圍內
</notin>
能夠把上面兩個標籤合併成爲:
<in name="id" value="1,2,3">
id在範圍內
<else/>
id不在範圍內
</in>
name屬性還能夠支持直接判斷系統變量,例如:
<in name="Think.get.id" value="1,2,3">
$_GET['id'] 在範圍內
</in>
value屬性也可使用變量,例如:
<in name="id" value="$range">
id在範圍內
</in>
$range變量能夠是數組,也能夠是以逗號分隔的字符串。
BETWEEN 和 NOTBETWEEN
可使用between標籤來判斷變量是否在某個區間範圍內,可使用:
<between name="id" value="1,10">
輸出內容1
</between>
一樣,可使用notbetween標籤來判斷變量不在某個範圍內:
<notbetween name="id" value="1,10">
輸出內容2
</notbetween>
也可使用else標籤把兩個用法合併,例如:
<between name="id" value="1,10">
輸出內容1
<else/>
輸出內容2
</between>
當使用between標籤的時候,value只須要一個區間範圍,也就是隻支持兩個值,後面的值無效,例如
<between name="id" value="1,3,10">
輸出內容1
</between>
實際判斷的範圍區間是1~3,而不是1~10,也能夠支持字符串判斷,例如:
<between name="id" value="A,Z">
輸出內容1
</between>
name屬性能夠直接使用系統變量,例如:
<between name="Think.post.id" value="1,5">
輸出內容1
</between>
value屬性也可使用變量,例如:
<between name="id" value="$range">
輸出內容1
</between>
賦值判斷標籤
可使用present、empty等標籤進行賦值判斷輸出。
present標籤用於判斷某個變量是否已經定義,用法:
<present name="name">
name已經賦值
<else />
name尚未賦值
</present>
name屬性能夠直接使用系統變量,例如:
<present name="Think.get.name">
$_GET['name']已經賦值
</present>
empty標籤用於判斷某個變量是否爲空,用法:
name爲空
name不爲空
name屬性能夠直接使用系統變量,例如:
<empty name="Think.get.name">
$_GET['name']爲空值
</empty>
DEFINED標籤用於判斷某個常量是否有定義,用法以下:
<defined name="NAME">
NAME常量已經定義
<else />
NAME常量未定義
</defined>
原生代碼
Php代碼能夠和標籤在模板文件中混合使用,能夠在模板文件裏面書寫任意的PHP語句代碼 ,包括下面兩種方式:
第一種:使用php標籤
例如:
<php>echo 'Hello,world!';</php>
咱們建議須要使用PHP代碼的時候儘可能採用php標籤,由於原生的PHP語法可能會被配置禁用而致使解析錯誤。
第二種:使用原生php代碼
<?php echo 'Hello,world!'; ?>
公共模板和模板佈局
咱們學習了模板的輸出後,就會發現不少應用存在大量的模板文件,如何簡化模板文件的定義和公共調用就成了關鍵,ThinkPHP的模板引擎內置了公共模板和佈局模板功能支持,能夠方便的規劃和公用你的模板文件。
公共模板
在當前模版文件中包含其餘公用的模版文件使用include標籤,標籤用法:
<include file='模版表達式或者模版文件1,模版表達式或者模版文件2,...' />
使用模版表達式
模版表達式的定義規則爲:
模塊@主題/控制器/操做
例如:
<include file="Public/header" /> // 包含頭部模版header
<include file="Public/menu" /> // 包含菜單模版menu
<include file="Blue/Public/menu" /> // 包含blue主題下面的menu模版
能夠一次包含多個模版,例如:
<include file="Public/header,Public/menu" />
,包含模版文件並不會自動調用控制器的方法,也就是說包含的其餘模版文件中的變量賦值須要在當前操做中完成。
論你使用什麼方式包含外部模板,Include標籤支持在包含文件的同時傳入參數,例如,下面的例子咱們在包含header模板的時候傳入了title和keywords變量:
<include file="Public/header" title="ThinkPHP框架" keywords="開源WEB開發框架" />
就能夠在包含的header.html文件裏面使用title和keywords變量,以下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>[title]</title>
<meta name="keywords" content="[keywords]" />
</head>
注意:若是外部模板有所更改,模板引擎並不會從新編譯模板,除非在調試模式下或者緩存已通過期。若是部署模式下修改了包含的外部模板文件後,須要把模塊的緩存目錄清空,不然沒法生效。
模板佈局
ction參數綁定
在以前的內容中,涉及的控制器操做方法都是沒有任何參數的,其實ThinkPHP能夠支持操做方法的參數綁定功能。
Action參數綁定是經過直接綁定URL地址中的變量做爲操做方法的參數,能夠簡化方法的定義甚至路由的解析,其原理是把URL中的參數(不包括模塊、控制器和操做名)和控制器的操做方法中的參數(按變量名或者變量順序)進行綁定。
按變量名綁定
默認的參數綁定方式是按照變量名進行綁定,例如,咱們給Blog控制器定義了兩個操做方法read和archive方法,因爲read操做須要指定一個id參數,archive方法須要指定年份(year)和月份(month)兩個參數,那麼咱們能夠以下定義:
<?php
namespace Home\Controller;
use Think\Controller;
class BlogController extends Controller{
public function read($id){
echo 'id='.$id;
}
public function archive($year='2013',$month='01'){
echo 'year='.$year.'&month='.$month;
}
}
注意這裏的操做方法並無具體的業務邏輯,只是簡單的示範。
URL的訪問地址分別是:
http://serverName/index.php/Home/Blog/read/id/5
http://serverName/index.php/Home/Blog/archive/year/2013/month/11
兩個URL地址中的id參數和year和month參數會自動和read操做方法以及archive操做方法的同名參數綁定。
變量名綁定不必定由訪問URL決定,路由地址也能起到相同的做用
輸出的結果依次是:
id=5
year=2013&month=11
按照變量名進行參數綁定的參數必須和URL中傳入的變量名稱一致,可是參數順序不須要一致。也就是說
http://serverName/index.php/Home/Blog/archive/month/11/year/2013
和上面的訪問結果是一致的,URL中的參數順序和操做方法中的參數順序均可以隨意調整,關鍵是確保參數名稱一致便可。
若是使用下面的URL地址進行訪問,參數綁定仍然有效:
http://serverName/index.php?s=/Home/Blog/read/id/5
http://serverName/index.php?s=/Home/Blog/archive/year/2013/month/11
http://serverName/index.php?c=Blog&a=read&id=5
http://serverName/index.php?c=Blog&a=archive&year=2013&month=11
若是用戶訪問的URL地址是(至於爲何會這麼訪問暫且不提):
http://serverName/index.php/Home/Blog/read/
那麼會拋出下面的異常提示: 參數錯誤:id
報錯的緣由很簡單,由於在執行read操做方法的時候,id參數是必須傳入參數的,可是方法沒法從URL地址中獲取正確的id參數信息。因爲咱們不能相信用戶的任何輸入,所以建議你給read方法的id參數添加默認值,例如:
public function read($id=0){
echo 'id='.$id;
}
這樣,當咱們訪問 http://serverName/index.php/Home/Blog/read/ 的時候 就會輸出
id=0
當咱們訪問 http://serverName/index.php/Home/Blog/archive/ 的時候,輸出:
year=2013&month=01
始終給操做方法的參數定義默認值是一個避免報錯的好辦法
按變量順序綁定的方式目前僅對PATHINFO地址有效,因此下面的URL訪問參數綁定會失效:
http://serverName/index.php?c=Blog&a=read&id=5
http://serverName/index.php?c=Blog&a=archive&year=2013&month=11
可是,兼容模式URL地址訪問依然有效:
http://serverName/index.php?s=/Home/Blog/read/5
http://serverName/index.php?s=/Home/Blog/archive/2013/11
若是你的操做方法定義都不帶任何參數或者不但願使用該功能的話,能夠關閉參數綁定功能:
'URL_PARAMS_BIND' => false
空操做是指系統在找不到請求的操做方法的時候,會定位到當前控制器的空操做(_empty)方法來執行。
例如,下面咱們用空操做功能來實現一個城市切換的功能。 咱們只須要給CityController類定義一個_empty方法:
<?php
namespace Home\Controller;
use Think\Controller;
class CityController extends Controller{
public function _empty($name){
//把全部城市的操做解析到city方法
$this->city($name);
}
//注意 city方法 自己是 protected 方法
protected function city($name){
//和$name這個城市相關的處理
echo '當前城市' . $name;
}
}
接下來,咱們就能夠在瀏覽器裏面輸入
http://serverName/index.php/Home/City/beijing/
http://serverName/index.php/Home/City/shanghai/
http://serverName/index.php/Home/City/shenzhen/
因爲City控制器並無定義beijing、shanghai或者shenzhen操做方法,所以系統會定位到空操做方法 _empty中去解析,_empty方法的參數就是當前URL裏面的操做名,所以會看到依次輸出的結果是:
當前城市:beijing
當前城市:shanghai
當前城市:shenzhen
複製代碼
注意:空操做方法僅在你的控制器類繼承系統的Think\Controller類纔有效。
空控制器
空控制器的概念是指當系統找不到請求的控制器名稱的時候,系統會嘗試定位空控制器(EmptyController)。
如今咱們把前面的需求進一步,把URL由原來的
http://serverName/index.php/Home/City/shanghai/
變成
http://serverName/index.php/Home/shanghai/
這樣更加簡單的方式,若是按照傳統的模式,咱們必須給每一個城市定義一個控制器類,而後在每一個控制器類的index方法裏面進行處理。但是若是使用空控制器功能,這個問題就能夠迎刃而解了。
咱們能夠給項目定義一個EmptyController類
<?php
namespace Home\Controller;
use Think\Controller;
class EmptyController extends Controller{
public function index(){
//根據當前控制器名來判斷要執行那個城市的操做
$cityName = CONTROLLER_NAME;
$this->city($cityName);
}
//注意 city方法 自己是 protected 方法
protected function city($name){
//和$name這個城市相關的處理
echo '當前城市' . $name;
}
}
接下來,咱們就能夠在瀏覽器裏面輸入
http://serverName/index.php/Home/beijing/
http://serverName/index.php/Home/shanghai/
http://serverName/index.php/Home/shenzhen/
因爲系統並不存在beijing、shanghai或者shenzhen控制器,所以會定位到空控制器(EmptyController)去執行,會看到依次輸出的結果是:
當前城市:beijing
當前城市:shanghai
當前城市:shenzhen
複製代碼
空控制器和空操做還能夠同時使用,用以完成更加複雜的操做。
前置和後置操做
_initialize方法是調用全部操做方法以前都會執行,前置和後綴操做則是針對某個特定的操做方法而言。
若是當前訪問的操做是存在(必須是實際在控制器中定義過)的,系統會檢測當前操做是否具備前置和後置操做,若是存在就會按照順序執行,前置和後置操做的方法名是在要執行的方法前面加 _before_和_after_,例如:
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller{
//前置操做方法
public function _before_index(){
echo 'before<br/>';
}
public function index(){
echo 'index<br/>';
}
//後置操做方法
public function _after_index(){
echo 'after';
}
}
若是咱們訪問 http://serverName/index.php
結果會輸出
before
index
after
對於任何操做方法咱們均可以按照這樣的規則來定義前置和後置方法。
若是在操做方法裏面使用了exit或者error方法的話 有可能不會再執行後置方法了,例如:
namespace Home\Controller;
use Think\Controller;
class IndexController extends Controller{
//前置操做方法
public function _before_index(){
echo 'before<br/>';
}
public function index(){
echo 'index<br/>';
exit;
}
//後置操做方法
public function _after_index(){
echo 'after';
}
}
若是咱們再次訪問結果會輸出
before
index
除了初始化、前置和後置操做以外,咱們還能夠在控制器之外的地方對操做方法進行擴展,這個之後會在行爲擴展部分描述。
頁面跳轉
系統的Think\Controller類內置了兩個頁面跳轉方法error和success,分別用於錯誤(提示)跳轉和成功(提示)跳轉。兩個方法都會輸出一個提示信息頁面,而後自動跳轉到指定的地址。下面是一個簡單的例子:
$New = M('New'); //實例化New對象
$result = $New->add($data);
if($result){
// 成功後跳轉到新聞列表頁面
$this->success('新增成功,即將返回列表頁面', '/New/index');
} else {
// 錯誤頁面的默認跳轉頁面是返回前一頁,一般不須要設置
$this->error('新增失敗');
}
success和error方法有三個參數,分別是提示信息、跳轉地址和跳轉頁面等待時間(秒),除了第一個參數外其餘都是可選的。
提示信息:成功或者錯誤信息字符串。
跳轉地址:頁面跳轉地址是可選的,success方法的默認跳轉地址是$_SERVER["HTTP_REFERER"],error方法的默認跳轉地址是javascript:history.back(-1);。
等待時間:默認的等待時間success方法是1秒,error方法是3秒。
success和error方法均可以對應的模板,默認兩個方法對應的模板是框架自帶的跳轉模板dispatch_jump.tpl:
//默認錯誤跳轉對應的模板文件
'TMPL_ACTION_ERROR' => THINK_PATH . 'Tpl/dispatch_jump.tpl',
//默認成功跳轉對應的模板文件
'TMPL_ACTION_SUCCESS' => THINK_PATH . 'Tpl/dispatch_jump.tpl',
success方法默認頁面顯示以下:
2015-06-06/557256edb73ad
error方法默認頁面顯示以下:
2015-06-06/557256c33274c
你能夠從新定義跳轉模板,一般建議直接放到項目目錄下面(下面採用公共模塊的模板做爲項目統一的跳轉模板):
//默認錯誤跳轉對應的模板文件
'TMPL_ACTION_ERROR' => 'Common@Public/error',
//默認成功跳轉對應的模板文件
'TMPL_ACTION_SUCCESS' => 'Common@Public/success',
模板文件可使用模板標籤,而且可使用下面的模板變量:
變量 含義
$message 頁面成功提示信息
$error 頁面錯誤提示信息
$waitSecond 跳轉等待時間 單位爲秒
$jumpUrl 跳轉頁面地址
重定向
若是不須要提示頁面,ThinkPHP還能夠實現直接重定向操做,Think\Controller類提供了redirect方法實現頁面的重定向功能。
重定向到操做
redirect('重定向操做地址(通常爲[控制器/操做])','參數(字符串或者數組)','重定向等待時間(秒)','重定向提示信息')
例如:
$New = M('New'); //實例化New對象
$result = $New->add($data);
if($result){
// 停留5秒後跳轉到New模塊的category操做,而且顯示頁面跳轉中字樣
$this->redirect('New/category', 'cate_id=2&status=1', 5,'頁面跳轉中...');
} else {
// 錯誤頁面
$this->redirect('New/error');
}
能夠傳入參數和設置重定向的等待時間,甚至給出等待的提示信息:
注意:重定向後會改變當前的URL地址。
重定向到URL
若是你僅僅是想重定向要一個指定的URL地址,而不是到控制器的操做方法,能夠直接使用redirect函數重定向,例如:
$New = M('New'); //實例化New對象
$result = $New->add($data);
if($result){
//重定向到指定的URL地址
redirect('/New/category/cate_id/2', 5, '頁面跳轉中...');
}
redirect函數的第一個參數是要跳轉的實際URL地址。
判斷請求類型
在不少狀況下面,咱們須要判斷當前操做的請求類型是GET 、POST 、PUT或 DELETE,一方面能夠針對請求類型做出不一樣的邏輯處理,另一方面有些狀況下面須要驗證安全性,過濾不安全的請求。
系統內置了一些常量用於判斷請求類型,包括:
常量 說明
IS_GET 判斷是不是GET方式提交
IS_POST 判斷是不是POST方式提交
IS_PUT 判斷是不是PUT方式提交
IS_DELETE 判斷是不是DELETE方式提交
IS_AJAX 判斷是不是AJAX提交
REQUEST_METHOD 當前提交類型
使用舉例以下:
class UserController extends Controller{
public function update(){
if (IS_POST){
$User = M('User');
$User->create();
$User->save();
$this->success('保存完成');
}else{
$this->error('非法請求');
}
}
}
個別狀況下判斷AJAX請求的時候,你可能須要在表單裏面添加一個隱藏域,告訴後臺屬於ajax方式提交,默認的隱藏域名稱是ajax(能夠經過VAR_AJAX_SUBMIT配置),若是是JQUERY類庫的話,則無需添加任何隱藏域便可自動判斷。
AJAX返回
ThinkPHP能夠很好的支持AJAX請求,系統的\Think\Controller類提供了ajaxReturn方法用於AJAX調用後返回數據給客戶端。而且支持JSON、JSONP、XML和EVAL四種方式給客戶端接受數據,而且支持配置其餘方式的數據格式返回。
ajaxReturn方法調用示例:
$data = 'ok';
$this->ajaxReturn($data);
支持返回數組數據:
$data['status'] = 1;
$data['content'] = 'content';
$this->ajaxReturn($data);
默認配置採用JSON格式返回數據(經過配置DEFAULT_AJAX_RETURN進行設置),咱們能夠指定格式返回,例如:
// 指定XML格式返回數據
$data['status'] = 1;
$data['content'] = 'content';
$this->ajaxReturn($data,'xml');
返回數據data能夠支持字符串、數字和數組、對象,返回客戶端的時候根據不一樣的返回格式進行編碼後傳輸。若是是JSON/JSONP格式,會自動編碼成JSON字符串,若是是XML方式,會自動編碼成XML字符串,若是是EVAL方式的話,只會輸出字符串data數據。
JSON和JSONP雖然只有一個字母的差異,但其實他們根本不是一回事兒:JSON是一種數據交換格式,而JSONP是一種非官方跨域數據交互協議。一個是描述信息的格式,一個是信息傳遞的約定方法。
默認的JSONP格式返回的處理方法是jsonpReturn,若是你採用不一樣的方法,能夠設置:
'DEFAULT_JSONP_HANDLER' => 'myJsonpReturn', // 默認JSONP格式返回的處理方法
URL僞靜態一般是爲了知足更好的SEO效果,ThinkPHP支持僞靜態URL設置,能夠經過設置URL_HTML_SUFFIX參數隨意在URL的最後增長你想要的靜態後綴,而不會影響當前操做的正常執行。
單個URL後綴
默認狀況下,僞靜態的設置爲html,所以下面的URL訪問是等效的:
http://serverName/Home/Blog/index
http://serverName/Home/Blog/index.html
但後者更具備靜態頁面的URL特徵,而且不會影響原來參數的使用。
但若是咱們訪問
http://serverName/Home/Blog/index.xml
則會提示出錯。
2015-06-06/55726422017c7
除非咱們設置了:
'URL_HTML_SUFFIX'=>'xml'
全後綴支持
若是咱們設置僞靜態後綴爲空,則能夠支持全部的靜態後綴訪問,而且會記錄當前的僞靜態後綴到常量 __EXT__ ,但不會影響正常的頁面訪問。
'URL_HTML_SUFFIX'=>''
設置後,下面的URL訪問都有效:
http://serverName/Home/blog/index.html
http://serverName/Home/blog/index.shtml
http://serverName/Home/blog/index.xml
http://serverName/Home/blog/index.pdf
能夠經過常量 __EXT__ 判斷當前訪問的後綴,例如:
if('pdf'==__EXT__){
// 輸出PDF文檔
}elseif('xml'==__EXT__){
// 輸出XML格式文檔
}
多個後綴支持
若是但願僅支持設置的多個僞靜態後綴訪問,能夠設置以下:
// 多個僞靜態後綴設置 用|分割
'URL_HTML_SUFFIX' => 'html|shtml|xml'
那麼,當訪問 http://serverName/Home/blog/index.pdf 的時候會報系統錯誤。
禁止訪問後綴
能夠設置禁止訪問的URL後綴,例如:
'URL_DENY_SUFFIX' => 'pdf|ico|png|gif|jpg', // URL禁止訪問的後綴設置
若是訪問 http://serverName/Home/blog/index.pdf 就會直接返回404錯誤。
意:
URL_DENY_SUFFIX的優先級比URL_HTML_SUFFIX要高。
在應用開發中, 常常會遇到一些帶有提示信息的跳轉頁面, 例如操做成功或者操做錯誤頁面, 而且自動跳
轉到另一個目標頁面。 系統的 \Think\Controller 類內置了兩個跳轉方法success和error, 用於頁面跳轉
提示, 並且能夠支持ajax提交。
使用方法很簡單, 舉例以下:
$User = M('User'); //實例化User對象
$result = $User->add($data);
if($result){
//設置成功後跳轉頁面的地址, 默認的返回頁面是$_SERVER['HTTP_REFERER']
$this->success('新增成功', '/User/index');
} else {
//錯誤頁面的默認跳轉頁面是返回前一頁, 一般不須要設置
$this->error('新增失敗');
}
success和error方法的第一個參數表示提示信息, 第二個參數表示跳轉地址, 第三個參數是跳轉時間( 單
位爲秒) , 例如:
ThinkPHP3.2.3徹底開發手冊
本文檔使用 看雲 構建 - 77 -
// 操做完成3秒後跳轉到 /Article/index
$this->success('操做完成','/Article/index',3);
// 操做失敗5秒後跳轉到 /Article/error
$this->error('操做失敗','/Article/error',5);
跳轉地址是可選的, success方法的默認跳轉地址是 $_SERVER["HTTP_REFERER"] , error方法的默認跳
轉地址是 javascript:history.back(-1);
Thinkphp自動驗證規則(轉載)
樓主:dailinsonglin 時間:2013-06-03 13:45:28 點擊:2362 回覆:0 脫水模式 給他打賞 只看樓主 閱讀設置
其實說白了,這篇文章就是轉給本身看的,省的下次用的時候滿網絡找了。有須要的同窗也能夠看看。自動驗證是很是有用的一個技術。日常的驗證基本就是,用戶名是否爲空,用戶名是否重複,密碼,重複密碼是否一致。官方給的就是這些。那麼咱們不可能只用到這些,鐵定還有別的規則,因此下面這些規則供同窗借鑑,也供我本身借鑑。
array(‘name’,’/^[a-z]\w{3,}$/i’,’名字不符合要求!’);
array(‘password’,’/^[a-z]\w{6,30}$/i’,’密碼不符合要求!’);
array(‘account’,’/^[A-Za-z]+$/’,’帳號必須使用英文!’);
附上一些表單驗證中比較經常使用的正則表達式寫法:
匹配中文字符的正則表達式: [\一-\龥]
匹配雙字節字符(包括漢字在內):[^\x00-\xff]
匹配Email地址的正則表達式:\w+([-+.]\w+)*\w+([-.]\w+)*\.\w+([-.]\w+)*
匹配網址URL的正則表達式:[a-zA-z]+://[^\s]*
匹配賬號是否合法(字母開頭,容許5-16字節,容許字母數字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
匹配國內電話號碼:\d{3}-\d{8}|\d{4}-\d{7}
匹配中國郵政編碼:[1-9]\d{5}(?!\d)
匹配ip地址:\d+\.\d+\.\d+\.\d+
匹配特定數字:
^[1-9]\d*$ //匹配正整數
^-[1-9]\d*$ //匹配負整數
^-?[1-9]\d*$ //匹配整數
^[1-9]\d*|0$ //匹配非負整數(正整數 + 0)
^-[1-9]\d*|0$ //匹配非正整數(負整數 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ //匹配正浮點數
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ //匹配負浮點數
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$ //匹配浮點數
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$ //匹配非負浮點數(正浮點數 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$ //匹配非正浮點數(負浮點數 + 0)
匹配特定字符串:
^[A-Za-z]+$ //匹配由26個英文字母組成的字符串
^[A-Z]+$ //匹配由26個英文字母的大寫組成的字符串
^[a-z]+$ //匹配由26個英文字母的小寫組成的字符串
^[A-Za-z0-9]+$ //匹配由數字和26個英文字母組成的字符串
^\w+$ //匹配由數字、26個英文字母或者下劃線組成的字符串
實例:
protected $_validate = array(
array('username','require','用戶名必須!'), // 數據是否爲空 注:默認增長修改都驗證
array('username','','用戶名已經存在!',0,’unique’,1), // 在新增的時候驗證username字段是否惟一
array('password','checkPwd','密碼格式不正確',0,’function’), // 密碼格式能夠用chenkPwd方法自定義
array('repassword','password','確認密碼不正確',0,’confirm’), // 驗證確認密碼是否和密碼一致
array('sex','array(0,1,2)','性別必須爲0,1,2',0,'in'), // 驗證數據是否在一個範圍內
array('age','number','年齡必須爲數字'), // 驗證數據是否爲數字
array('email','email','郵箱格式不正確'), // 內置正則驗證郵箱
array('email','/^/w+([-+.]/w+)*/w+([-.]/w+)*/./w+([-.]/w+)*$/','郵箱格式不正確), // 自定義正則驗證數據
array('mypage','url','我的網址格式不正確'), // 內置正則驗證URL地址
array('verify','****','驗證碼不正確',0,'equal'), // 驗證數據是否等於某個值 注:****能夠是隨機驗證碼
array('salary','currency','薪水驗證不正確','0'), // 內置驗證貨幣數據
);
文章均屬 松林's blog 原創 轉載請註明轉自松林's blog
//檢查url
public function check_url($url){
if(!preg_match('/http:\/\/[\w.]+[\w\/]*[\w.]*\??[\w=&\+\%]*/is',$url)){
return false;
}
return true;
}
模板輸出變量
{$name}
Email: {$data.email}
或者用下面的方式也是有效:
Name: {$data['name']}
對象
Email: {$data:email}
或者
Name: {$data->name}
{$Think.server.script_name} // 輸出$_SERVER['SCRIPT_NAME']變量 系統變量
常量
{$Think.const.MODULE_NAME}
前言
A標籤是html中經常使用的標籤,它與button按鈕是實現頁面跳轉的兩種最經常使用的方式,常常在開發中咱們更喜歡使用A標籤,它們二者能夠相互替換,但他們在執行js腳本時有着細微的區別。
使用A標籤執行JS腳本的幾種方式
一、href="javascript:js_method();"
這是咱們最經常使用的方法,可是這種方法在傳遞this等參數的時候很容易出問題,並且javascript:協議做爲a的href屬性的時候不只會致使沒必要要的觸發window.onbeforeunload事件,在IE裏面更會使gif動畫圖片中止播放。W3C標準不推薦在href裏面執行javascript語句。
二、href="javascript:void(0);" onclick="js_method()"
這種方法是不少網站最經常使用的方法,也是最周全的方法,onclick方法負責執行js函數,而void是一個操做符,void(0)返回undefined,地址不發生跳轉。並且這種方法不會像第一種方法同樣直接將js方法暴露在瀏覽器的狀態欄,推薦使用此方法。
三、href="javascript:;" onclick="js_method()"
這種方法跟跟第2種相似,區別只是執行了一條空的js代碼。Href與onclick區別是每一個href裏的javascript方法都用try、catch包圍。
四、href="#" onclick="js_method()"
這種方法也是網上很常見的代碼,#是標籤內置的一個方法,表明top的做用。因此用這種方法點擊後網頁後返回到頁面的最頂端。
五、href="#" onclick="js_method();return false;"
這種方法點擊執行了js函數後return false,頁面不發生跳轉,執行後仍是在頁面的當前位置。
綜合上述,在a中調用js函數最適當的方法推薦使用後幾種,注意第四種會返回頁面最頂端,當有這種需求時可使用。
模型的名字要和數據庫表對應。
可是若是不對應,要進行定義數據表的名字。
在數據庫裏面有一個 think_categories 表, 而咱們定義的模型類名稱是
CategoryModel , 按照系統的約定, 這個模型的名稱是Category, 對應的數據表名稱應該是
think_category ( 所有小寫) , 可是如今的數據表名稱是 think_categories , 所以咱們就須要設置
tableName 屬性來改變默認的規則( 假設咱們已經在配置文件裏面定義了 DB_PREFIX 爲 think_) 。
namespace Home\Model;
use Think\Model;
class CategoryModel extends Model {
protected $tableName = 'categories';
}
注意這個屬性的定義不須要加表的前綴 think_
若是咱們須要CategoryModel模型對應操做的數據表是 top_category , 那麼咱們只須要設置數據表前綴
便可:
namespace Home\Model;
use Think\Model;
class CategoryModel extends Model {
protected $tablePrefix = 'top_';
}
若是你的數據表直接就是 category , 而沒有前綴, 則能夠設置 tablePrefix 爲空字符串。
namespace Home\Model;
use Think\Model;
class CategoryModel extends Model {
protected $tablePrefix = '';
}
沒有表前綴的狀況必須設置, 不然會獲取當前配置文件中的 DB_PREFIX 。
ThinkPHP3.2.3徹底開發手冊
本文檔使用 看雲 構建 - 93 -
而對於另一種特殊狀況, 咱們須要操做的數據表是 top_categories , 這個時候咱們就須要定義
trueTableName 屬性
namespace Home\Model;
use Think\Model;
class CategoryModel extends Model {
protected $trueTableName = 'top_categories';
}
注意 trueTableName 須要完整的表名定義。
除了數據表的定義外, 還能夠對數據庫進行定義( 用於操做當前數據庫之外的數據表) , 例如
top.top_categories :
namespace Home\Model;
use Think\Model;
class CategoryModel extends Model {
protected $trueTableName = 'top_categories';
protected $dbName = 'top';
}
D方法 數據模型實例化
$User = D('User');
$User->select();
D方法的參數就是模型的名稱, 而且和模型類的大小寫定義是一致的.
D方法能夠自動檢測模型類, 若是存在自定義的模型類, 則實例化自定義模型類, 若是不存在, 則會實例
化系統的\Think\Model基類, 同時對於已實例化過的模型, 不會重複實例化
D方法還能夠支持跨模塊調用, 須要使用:
//實例化Admin模塊的User模型
D('Admin/User');
//實例化Extend擴展命名空間下的Info模型
D('Extend://Editor/Info');
D方法實例化模型類的時候一般是實例化某個具體的模型類, 若是你僅僅是對數據表進行基本的CURD操做
的話, 使用M方法實例化的話, 因爲不須要加載具體的模型類, 因此性能會更高。
例如:
// 使用M方法實例化
$User = M('User');
// 和用法 $User = new \Think\Model('User'); 等效
// 執行其餘的數據操做
$User->select();
M方法也能夠支持跨庫操做, 例如:
// 使用M方法實例化 操做db_name數據庫的ot_user表
$User = M('db_name.User','ot_');
// 執行其餘的數據操做
$User->select();
M方法的參數和\Think\Model類的參數是同樣的, 也就是說, 咱們也能夠這樣實例化:
$New = M('new','think_',$connection);
// 等效於 $New = new \Think\Model('new','think_',$connection);
具體的參數含義能夠參考前面的介紹。
M方法實例化的時候, 默認狀況下是直接實例化系統的\Think\Model類, 若是咱們但願實例化其餘的公共
模型類的話, 可使用以下方法:
$User = M('\Home\Model\CommonModel:User','think_','db_config');
// 至關於 $User = new \Home\Model\CommonModel('User','think_','db_config');
實例化空模型類
若是你僅僅是使用原生SQL查詢的話, 不須要使用額外的模型類, 實例化一個空模型類便可進行操做了,
例如:
//實例化空模型
$Model = new Model();
//或者使用M快捷方法是等效的
$Model = M();
//進行原生的SQL查詢
$Model->query('SELECT * FROM think_user WHERE status = 1');
實例化空模型類後還能夠用table方法切換到具體的數據表進行操做
咱們在實例化的過程當中, 常用D方法和M方法, 這兩個方法的區別在於M方法實例化模型無需用戶爲
每一個數據表定義模型類, 若是D方法沒有找到定義的模型類, 則會自動調用M方法。
若是須要顯式獲取當前數據表的字段信息, 可使用模型類的getDbFields方法來獲取當前數據對象的全
部字段信息, 例如:
$User = M('User');
$fields = $User->getDbFields();
若是你在部署模式下面修改了數據表的字段信息, 可能須要清空 Data/_fields 目錄下面的緩存文件, 讓系
統從新獲取更新的數據表字段信息, 不然會發生新增的字段沒法寫入數據庫的問題
<if condition="$info['logo'] neq ''"> <span style="float:left;padding-righ:10px"><img src="{weiwin:$info.logo}"/></span>
</if>{weiwin:$info.info}</div>
js跳轉到其餘控制器還有方法 window.location.href='index.php?g=Wap&m=Card&a=index&token='+token+'&wecha_id='+wid;
URL大小寫
可是系統自己提供了一個不區分URL大小寫的解決方案,能夠經過配置簡單實現。
只要在項目配置中,增長:
'URL_CASE_INSENSITIVE' =>true
配置好後,即便是在Linux環境下面,也能夠實現URL訪問再也不區分大小寫了。
http://serverName/index.php/Home/Index/index
// 將等效於
http://serverName/index.php/home/index/index
這裏須要注意一個地方,一旦開啓了不區分URL大小寫後,若是咱們要訪問相似UserTypeController的控制器,那麼正確的URL訪問應該是:
// 正確的訪問地址
http://serverName/index.php/home/user_type/index
// 錯誤的訪問地址(linux環境下)
http://serverName/index.php/home/usertype/index
利用系統提供的U方法能夠爲你自動生成相關的URL地址。
3.2.3版本開始,I函數支持對變量使用修飾符功能,能夠更好的過濾變量。
用法以下: I('變量類型.變量名/修飾符');
例如:
I('get.id/d');
I('post.name/s');
I('post.ids/a');
可使用的修飾符包括:
修飾符 做用
s 強制轉換爲字符串類型
d 強制轉換爲整形類型
b 強制轉換爲布爾類型
a 強制轉換爲數組類型
f 強制轉換爲浮點類型
請求類型
在不少狀況下面,咱們須要判斷當前操做的請求類型是GET 、POST 、PUT或 DELETE,一方面能夠針對請求類型做出不一樣的邏輯處理,另一方面有些狀況下面須要驗證安全性,過濾不安全的請求。 系統內置了一些常量用於判斷請求類型,包括:
常量 說明
IS_GET 判斷是不是GET方式提交
IS_POST 判斷是不是POST方式提交
IS_PUT 判斷是不是PUT方式提交
IS_DELETE 判斷是不是DELETE方式提交
IS_AJAX 判斷是不是AJAX提交
REQUEST_METHOD 當前提交類型
class UserController extends Controller{
public function update(){
if (IS_POST){
$User = M('User');
$User->create();
$User->save();
$this->success('保存完成');
}else{
$this->error('非法請求');
}
}
}
須要注意的是,若是使用的是ThinkAjax或者本身寫的Ajax類庫的話,須要在表單裏面添加一個隱藏域,告訴後臺屬於ajax方式提交,默認的隱藏域名稱是ajax(能夠經過VAR_AJAX_SUBMIT配置),若是是JQUERY類庫的話,則無需添加任何隱藏域便可自動判斷。
下面咱們用空操做功能來實現一個城市切換的功能。 咱們只須要給CityController類定義一個_empty(空操做)方法:
<?php
namespace Home\Controller;
use Think\Controller;
class CityController extends Controller{
public function _empty($name){
//把全部城市的操做解析到city方法
$this->city($name);
}
//注意 city方法 自己是 protected 方法
protected function city($name){
//和$name這個城市相關的處理
echo '當前城市' . $name;
}
}
success和error方法的第一個參數表示提示信息,第二個參數表示跳轉地址,第三個參數是跳轉時間(單位爲秒),例如:
// 操做完成3秒後跳轉到 /Article/index
$this->success('操做完成','/Article/index',3);
// 操做失敗5秒後跳轉到 /Article/error
$this->error('操做失敗','/Article/error',5);
跳轉地址是可選的,success方法的默認跳轉地址是$_SERVER["HTTP_REFERER"],error方法的默認跳轉地址是javascript:history.back(-1);。
默認的等待時間success方法是1秒,error方法是3秒
success和error方法均可以對應的模板,默認的設置是兩個方法對應的模板都是:
//默認錯誤跳轉對應的模板文件
'TMPL_ACTION_ERROR' => THINK_PATH . 'Tpl/dispatch_jump.tpl',
//默認成功跳轉對應的模板文件
'TMPL_ACTION_SUCCESS' => THINK_PATH . 'Tpl/dispatch_jump.tpl',
也可使用項目內部的模板文件
//默認錯誤跳轉對應的模板文件
'TMPL_ACTION_ERROR' => 'Public:error';
//默認成功跳轉對應的模板文件
'TMPL_ACTION_SUCCESS' => 'Public:success';
模板文件可使用模板標籤,而且可使用下面的模板變量:
變量 含義
$msgTitle 操做標題
$message 頁面提示信息
$status 操做狀態 1表示成功 0 表示失敗 具體還能夠由項目自己定義規則
$waitSecond 跳轉等待時間 單位爲秒
$jumpUrl 跳轉頁面地址
success和error方法會自動判斷當前請求是否屬於Ajax請求,若是屬於Ajax請求則會調用ajaxReturn方法返回信息。 ajax方式下面,success和error方法會封裝下面的數據返回:
$data['info'] = $message; // 提示信息內容
$data['status'] = $status; // 狀態 若是是success是1 error 是0
$data['url'] = $jumpUrl; // 成功或者錯誤的跳轉地址
重定向
Controller類的redirect方法能夠實現頁面的重定向功能。
redirect方法的參數用法和U函數的用法一致(參考URL生成部分),例如:
//重定向到New模塊的Category操做
$this->redirect('New/category', array('cate_id' => 2), 5, '頁面跳轉中...');
上面的用法是停留5秒後跳轉到New模塊的category操做,而且顯示頁面跳轉中字樣,重定向後會改變當前的URL地址。
若是你僅僅是想重定向要一個指定的URL地址,而不是到某個模塊的操做方法,能夠直接使用redirect函數重定向,例如:
//重定向到指定的URL地址
redirect('/New/category/cate_id/2', 5, '頁面跳轉中...')
Redirect函數的第一個參數是一個URL地址。
控制器的redirect方法和redirect函數的區別在於前者是用URL規則定義跳轉地址,後者是一個純粹的URL地址。