Thinkphp5.1應用初探
直接審計tp的話應該會很有難度,不妨先了解一些tp內建規則和用法,便於在後續的審計中更好的理解程式碼含義。
安裝
沒有composer可以去下載,傻瓜式安裝即可Composer (getcomposer.org)
使用composer安裝
composer create-project topthink/think tp
啟動服務
cd tp php think run
然後就可以在瀏覽器中訪問
http://localhost:8000
搭建成功
目錄結構
www WEB部署目錄(或者子目錄) application 應用目錄 common 公共模組目錄(可以更改) module_name 模組目錄 common.php 模組函式檔案 controller 控制器目錄 model 模型目錄 view 檢視目錄 ... 更多類庫目錄 command.php 命令列定義檔案 common.php 公共函式檔案 tags.php 應用行為擴充套件定義檔案 config 應用配置目錄 module_name 模組配置目錄 database.php 資料庫配置 cache 快取配置 ... app.php 應用配置 cache.php 快取配置 cookie.php Cookie配置 database.php 資料庫配置 log.php 日誌配置 session.php Session配置 template.php 模板引擎配置 trace.php Trace配置 route 路由定義目錄 route.php 路由定義 ... 更多 public WEB目錄(對外訪問目錄) index.php 入口檔案 router.php 快速測試檔案 .htaccess 用於apache的重寫 thinkphp 框架系統目錄 lang 語言檔案目錄 library 框架類庫目錄 think Think類庫包目錄 traits 系統Trait目錄 tpl 系統模板目錄 base.php 基礎定義檔案 console.php 控制檯入口檔案 convention.php 框架慣例配置檔案 helper.php 助手函式檔案 phpunit.xml phpunit配置檔案 start.php 框架入口檔案 extend 擴充套件類庫目錄 runtime 應用的執行時目錄(可寫,可定製) vendor 第三方類庫目錄(Composer依賴庫) build.php 自動生成定義檔案(參考) composer.json composer 定義檔案 LICENSE.txt 授權說明檔案 README.md README 檔案 think 命令列入口檔案
命名規範
ThinkPHP5
遵循PSR-2命名規範和PSR-4自動載入規範,並且注意如下規範:
目錄和檔案
- 目錄不強制規範,駝峰和小寫+下劃線模式均支援;
- 類庫、函式檔案統一以
.php
為字尾; - 類的檔名均以名稱空間定義,並且名稱空間的路徑和類庫檔案所在路徑一致;
- 類名和類檔名保持一致,統一採用駝峰法命名(首字母大寫);
函式和類、屬性命名
- 類的命名採用駝峰法,並且首字母大寫,例如
User
、UserType
,預設不需要新增字尾,例如UserController
應該直接命名為User
; - 函式的命名使用小寫字母和下劃線(小寫字母開頭)的方式,例如
get_client_ip
; - 方法的命名使用駝峰法,並且首字母小寫,例如
getUserName
; - 屬性的命名使用駝峰法,並且首字母小寫,例如
tableName
、instance
; - 以雙下劃線“__”打頭的函式或方法作為魔法方法,例如
__call
和__autoload
;
常量和配置
- 常量以大寫字母和下劃線命名,例如
APP_PATH
和THINK_PATH
; - 配置引數以小寫字母和下劃線命名,例如
url_route_on
和url_convert
;
資料表和欄位
- 資料表和欄位採用小寫加下劃線方式命名,並注意欄位名不要以下劃線開頭,例如
think_user
表和user_name
欄位,不建議使用駝峰和中文作為資料表欄位命名。
URL解析模式
http://localhost/index.php/模組/控制器/操作/引數/值
如果使用的是偽靜態,就不必加上/thinkphp/tp5/public/index.php/
了
http://127.0.0.1:8000/index/index/hello/name/Sentiment
在url位址列裡面如果不寫模組、控制器和操作名,預設訪問的就是index模組下面的index控制器下面的index操作,可以在config/app.php檔案中進行修改。
控制器定義
控制器,即 controller,控制器檔案存放在 controller 目錄下
類名和檔名大小寫保持一致,採用駝峰法()
如果類名是 雙字母組合,比如 class HelloWorld,url 訪問時必須用:hello_world;
想要原樣方式訪問 URL,則需要關閉配置檔案中的自動轉換
‘url_convert’ => false;
在Test模組下,定義一個HelloWorld控制器,test操作
<?php namespace app\test\controller; class HelloWorld{ public function test(){ return 'hello_world!!!!!'; } }
訪問HelloWorld控制器時,就必須以hello_world形式才行
渲染輸出
使用 view 輸出模板
方法同名檔案
tp中內建了一個view()方法,它可以找到同模組下的view/控制器同名資料夾(這裡就是test)/與方法同名的檔案.html(定義的是show方法,所以會自動追蹤到show.html)
根據url解析模式,直接訪問test模組,test控制器,show操作
不同名檔案
若不是方法同名.html,在view()中加上對應的html檔名即可(`view/同名控制器/引數同名.html)
資料庫操作
資料庫配置在config/database.php下,資料庫操作分為兩種型別:DB類,模型類
這裡先設定下資料庫名,使用者名稱,密碼,表字首可選我這裡填的think_
下一步就是建立資料庫了,在think資料庫的think_data表下建立三個欄位
DB類
原生查詢
支援query
(查詢操作)和execute
(寫入操作)方法
新增資料
<?php namespace app\test\controller; use think\Db; class Data{ public function index(){ $resault = Db::execute('insert into think_data (id,name,status) values(1,"Sentiment",1)'); return dump($resault); } }
訪問方法
執行成功
再插入一條
$resault = Db::execute('insert into think_data (id,name,status) values(1,"Tana",1)');
更新資料
<?php namespace app\test\controller; use think\Db; class Data{ public function index(){ $resault = Db::execute('update think_data set id=2 where name="Sentiment"'); return dump($resault); } }
刪除資料
<?php namespace app\test\controller; use think\Db; class Data{ public function index(){ $resault = Db::execute('delete from think_data where name ="Tana"'); return dump($resault); } }
查詢資料
query用於查詢,預設情況下返回陣列集,execute方法的返回值是影響的行數
<?php namespace app\test\controller; use think\Db; class Data{ public function index(){ $resault = Db::query('select * from think_data'); return dump($resault); } }
查詢構造器
新增資料
透過insert語句新增資料,如果設定了表字首(prefix)則可以使用name(表字尾),若沒設定則需全名即:table(think_data),也可應inserAll插入多條資料
<?php namespace app\test\controller; use think\Db; class Data{ public function index(){ $data=['id' => 1, 'name' => 'Sentiment','status'=>1]; $resault = Db::name('data')->insert($data); return dump($resault); } }
更新資料
可以用update語句,也可以是tp封裝的setField,同時若需要欄位自增/自減也可以用setInc/setDec
<?php namespace app\test\controller; use think\Db; class Data{ public function index(){ $resault = Db::name('data')->where('name', "Sentiment")->update(['id' => '2']); //tp5封裝函式 $resault = Db::name('data')->where('name', "Sentiment")->setField('id',2); //不給第二個引數,預設為1 $resault = Db::name('data')->where('name', "Sentiment")->setInc('id'); //自減2 $resault = Db::name('data')->where('name', "Sentiment")->setDec('id',2); return dump($resault); } }
刪除資料
<?php namespace app\test\controller; use think\Db; class Data{ public function index(){ $resault = Db::name('data')->where('name', "Tana")->delete(); return dump($resault); } }
查詢資料
<?php namespace app\test\controller; use think\Db; class Data{ public function index(){ $resault = Db::name('data')->select(); return dump($resault); } }
助手函式
用 $db=\db('data');
代替Db::name('data')
,db 助手函式預設會每次重新連線資料庫,因此應當儘量避免多次呼叫。
<?php namespace app\test\controller; use think\Db; class Data{ public function index(){ $db=\db('data'); $resault=$db->select(); return dump($resault); } }
鏈式操作
資料庫提供的鏈式操作方法,可以有效的提高資料存取的程式碼清晰度和開發效率,並且支援所有的CURD操作(原生查詢不支援鏈式操作)。
鏈式操作不分先後,只要在查詢方法(select()、find())前呼叫就行
Db::name('data') -> where('status',1) -> order('create_time') -> limit(10) -> select();
鏈式操作查詢方法
連貫操作 | 作用 | 支援的引數型別 |
---|---|---|
where* | 用於AND查詢 | 字串、陣列和物件 |
whereOr* | 用於OR查詢 | 字串、陣列和物件 |
wheretime* | 用於時間日期的快捷查詢 | 字串 |
table | 用於定義要操作的資料表名稱 | 字串和陣列 |
alias | 用於給當前資料表定義別名 | 字串 |
field* | 用於定義要查詢的欄位(支援欄位排除) | 字串和陣列 |
order* | 用於對結果排序 | 字串和陣列 |
limit | 用於限制查詢結果數量 | 字串和數字 |
page | 用於查詢分頁(內部會轉換成limit) | 字串和數字 |
group | 用於對查詢的group支援 | 字串 |
having | 用於對查詢的having支援 | 字串 |
join* | 用於對查詢的join支援 | 字串和陣列 |
union* | 用於對查詢的union支援 | 字串、陣列和物件 |
view* | 用於檢視查詢 | 字串、陣列 |
distinct | 用於查詢的distinct支援 | 布林值 |
lock | 用於資料庫的鎖機制 | 布林值 |
cache | 用於查詢快取 | 支援多個引數 |
relation* | 用於關聯查詢 | 字串 |
with* | 用於關聯預載入 | 字串、陣列 |
bind* | 用於資料繫結操作 | 陣列或多個引數 |
comment | 用於SQL註釋 | 字串 |
force | 用於資料集的強制索引 | 字串 |
master | 用於設定主伺服器讀取資料 | 布林值 |
strict | 用於設定是否嚴格檢測欄位名是否存在 | 布林值 |
sequence | 用於設定Pgsql的自增序列名 | 字串 |
failException | 用於設定沒有查詢到資料是否丟擲異常 | 布林值 |
partition | 用於設定分表資訊 | 陣列 字串 |
查詢表示式
select()用於查詢資料集,查詢成功則返回一個二維陣列,如果沒有滿足條件則返回空陣列
find()用於查詢滿足條件的第一個記錄,如果查詢成功,返回一個以為陣列,如果失敗則返回null
表示式 | 含義 | 快捷查詢方法 |
---|---|---|
= | 等於 | |
<> | 不等於 | |
> | 大於 | |
>= | 大於等於 | |
< | 小於 | |
<= | 小於等於 | |
[NOT] LIKE | 模糊查詢 | whereLike/whereNotLike |
[NOT] BETWEEN | (不在)區間查詢 | whereBetween/whereNotBetween |
[NOT] IN | (不在)IN 查詢 | whereIn/whereNotIn |
[NOT] NULL | 查詢欄位是否(不)是NULL | whereNull/whereNotNull |
[NOT] EXISTS | EXISTS查詢 | whereExists/whereNotExists |
[NOT] REGEXP | 正則(不)匹配查詢(僅支援Mysql) | |
[NOT] BETWEEM TIME | 時間區間比較 | whereBetweenTime |
> TIME | 大於某個時間 | whereTime |
< TIME | 小於某個時間 | whereTime |
>= TIME | 大於等於某個時間 | whereTime |
<= TIME | 小於等於某個時間 | whereTime |
EXP | 表示式查詢,支援SQL語法 | whereExp |
比較查詢
查詢id不等於1的資料
<?php namespace app\test\controller; use think\Db; class Data{ public function index(){ $result = Db::name('data')->where("id",'<>','1')->select(); return dump($result); } }
區間查詢
<?php namespace app\test\controller; use think\Db; class Data{ public function index(){ //模糊查詢name中帶n的資料 //$result = Db::name('data')->where("name",'like','%n%')->select(); //區間查詢id為1-3的資料 $result = Db::name('data')->where("id",'BETWEEN','[1,3]')->select(); return dump($result); } }
時間查詢
查詢2022-5-11以後的資料
$result = Db::name('data')->where("create_time",'> TIME','2022-5-11')->select();
其它查詢
查詢id=1或3的資料
$result = Db::name('data')->where("id",'EXP','IN (1,3)')->select(); 或 $result = Db::name('data')->whereExp("id",'IN (1,3)')->select();
模型類
在模型中除了可以呼叫資料庫類的方法之外(換句話說,資料庫的所有查詢方法模型中都可以支援),可以定義自己的方法,所以也可以把模型看成是資料庫的增強版。
模型定義
先建個think_user表
在test/model下建個think_user模型User,這裡的模型名=表名,所以必須叫User
新增資料
建好模型就開始資料庫操作了,use部分用到的就是剛剛定義的User,但為了不與控制器重名加了個as,這裡用了兩種方式新增資料
<?php namespace app\test\controller; use app\test\model\User as UserModel; class User { public function insert() { // $user = new UserModel(); // $user->id=1; // $user->name = 'Sentiment'; // $user->email = 'Sentiment@qq.com'; // $user->birthday=strtotime('2001-12-7'); // $user->save(); //陣列形式自定義 $user['id']=2; $user['name']='Tana'; $user['email']='Tana@qq.com'; $user['birthday']=strtotime('2000-1-1'); UserModel::create($user); } }
訪問test/user/insert,執行成功(注:這裡定義了四個欄位,所以在insert時候必須都加上,一開始以為會自動建立id就沒加,結果一直沒成功)
批次新增
也可以透過saveAll,批次新增
public function insertList(){ $user = new UserModel(); $list=[ ['id'=>'3','name'=>'Mumu','email'=>'Mumu@qq.com','birthday'=>strtotime('2002-1-1')], ['id'=>'4','name'=>'Shelter','email'=>'Shelter@qq.com','birthday'=>strtotime('2003-1-1')] ]; if($user->saveAll($list)){ return 'Success'; }else{ return 'faild'; } }
更新資料
查詢並更新
get獲取id=1的資料
public function update(){ $user = UserModel::get(1); $user->name='Mumu'; $user->email='Mumu@qq.com'; $user->birthday=strtotime('2002-1-1'); $user->save(); #dump($user); }
直接更新資料
$user = new UserModel(); $user->save(['name'=>'Shelter','email'=>'Shelter@qq.com'],['id'=>1]);
批次更新
$user = new UserModel(); $list=[ ['id'=>'3','name'=>'Mumu','email'=>'Mumu@qq.com','birthday'=>strtotime('2002-1-1')], ['id'=>'4','name'=>'Shelter','email'=>'Shelter@qq.com','birthday'=>strtotime('2003-1-1')] ];
透過資料庫類更新
$user = new UserModel(); $user->where('id',1)->update(['name'=>'Sentiment']); //包括主鍵的話也可以用下邊這種方法 //$user->update(['id'=>1,'name'=>'Tana']);
靜態方法
UserModel::where('id',1)->update(['name'=>'Sentiment']); //包括主鍵的話也可以用下邊這種方法 //UserModel::update(['id'=>1,'name'=>'Tana']);
查詢資料
查詢單個資料
//獲取單個資料 $user=UserModel::get(1); echo $user->name; //使用陣列查詢 $user=UserModel::get(1); echo $user->email; //例項化模型後查詢 $user = new UserModel(); $result = $user -> where('name','Sentiment')->find(); echo $result->name;
查詢多個資料
// 獲取多個資料 //$list=UserModel::all('1,2'); // 陣列形式 //$list=UserModel::all([1,2]); //foreach ($list as $key=>$value){ // echo $value->name; // } // 例項化模型後查詢 $user = new UserModel(); echo $user->where('id',1)->limit(2)->order('birthday','desc')->select();
刪除資料
//刪除當前模型 $user = UserModel::get(1); $user->delete(); //根據主鍵刪除 UserModel::destroy(1); //也可以刪除多個 UserModel::destroy('1,2'); UserModel::destroy([1,2]); //條件刪除 UserModel::destroy(['id'=>1]); UserModel::where('id','>',0)->delete();
檢視
檢視功能由\think\View
類配合檢視驅動(也即模板引擎驅動)類一起完成,目前的內建模板引擎包含PHP原生模板和Think模板引擎。
渲染模板最常用的是控制器類在繼承系統控制器基類(\think\Controller
)後呼叫fetch
方法,呼叫格式:
fetch('[模板檔案]'[,'模板變數(陣列)'])
常用方法:
方法 | 說明 |
---|---|
fetch | 渲染模板輸出 |
display | 渲染內容輸出 |
assign | 模板變數賦值 |
engine | 初始化模板引擎 |
檢視渲染
不給任何引數情況下預設返回,當前檔案/view/控制器名/方法名.html
<?php namespace app\test\controller; use think\Controller; class See extends Controller{ public function index(){ // 自動定位 //return $this->fetch(); //test/view/see/index.html // 指定模板 //return $this->fetch('test'); //test/view/see/test.html //指定目錄 //return $this->fetch('test/show'); //test/view/test/show.html // 指定模組下的模板,適用於多模組 //return $this->fetch('admin@public/test'); //admin/view/public/test.html //view_path 下的模組 //return $this->fetch('/Sentiment'); //test/view/Sentiment.html // 如果沒有繼承 Controller 模組的話,可以使用助手函式 view() 方法,具體使用方法同上 return view(); //test/view/see/index.html } }
檢視賦值
檢視賦值主要透過assign函式
assign賦值
//test/controller/Assign.php <?php namespace app\test\controller; use think\Controller; class Assign extends Controller{ public function index(){ //模板變數賦值 $name='Sentiment'; $age=18; // $this->assign('name',$name); // $this->assign('age',$age); //也可以透過陣列賦值 $this->assign([ 'name'=>$name, 'age'=>$age, ]); return $this->fetch(); } }
想輸出變數直接{$name}即可
/test/view/assign/index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Assign Test</title> </head> <body> this is assign/index.html</br> {$name}</br> {$age} </body> </html>
訪問/test/assign/index方法 成功返回body內容及變數值
fetch賦值
return $this->fetch('index',['name'=>$name,'age'=>$age]);
助手函式
return view('index',['name'=>$name,'age'=>$age]);
display方法
return $this->display('{$name} {$age}',['name'=>'Tana','age'=>$age]);
檢視過濾
filter()函式過濾
<?php namespace app\test\controller; use think\Controller; class Assign extends Controller{ public function index(){ //檢視過濾 $this->assign(['name' => 'Sentiment6', 'age'=>186]); return $this->filter(function ($content) { return str_replace('6', '<br>', $content); })->fetch(); } }
將6替換成了<br/>
初始化中全域性過濾
<?php namespace app\test\controller; use think\Controller; class Assign extends Controller{ public function index(){ $this->assign(['name' => 'Sentiment6', 'age'=>186]); return $this->fetch(); } public function initialize() { return $this->filter(function ($content) { return str_replace('6', '<br>', $content); }); } }
助手函式
<?php namespace app\test\controller; use think\Controller; class Assign extends Controller{ public function index(){ $this->assign(['name' => 'Sentiment6', 'age'=>186]); return view('index')->filter( function ($content) { return str_replace('6', '<br>', $content); } ); } }
模板
變數輸出
普通輸出方式
//test/controller/Assign.php <?php namespace app\test\controller; use think\Controller; class Assign extends Controller{ public function index(){ $this->assign('name', 'Sentiment'); return $this->fetch(); } }
模板
//test/view/assign/index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Assign Test</title> </head> <body> this is assign/index.html</br> Hello {$name} </body> </html>
系統變數輸出
{$Think.server.script_name} // 輸出$_SERVER['SCRIPT_NAME']變數 {$Think.session.user_id} // 輸出$_SESSION['user_id']變數 {$Think.get.page} // 輸出$_GET['page']變數 {$Think.cookie.name} // 輸出$_COOKIE['name']變數
在index.html中加上{$Think.server.script_name},即可輸出對應的script_name值
常量輸出
{$Think.const.PHP_VERSION} 或 {$Think.PHP_VERSION}
在Assign.php
中定義個常量
define('AAA','this is define');
在index.html加上
{$Think.AAA}
配置輸出
{$Think.config.default_module} {$Think.config.default_controller}
語言配置
{$Think.lang.page_error} {$Think.lang.var_error}
使用函式
過濾方法 | 描述 |
---|---|
date | 日期格式化(支援各種時間型別) |
format | 字串格式化 |
upper | 轉換為大寫 |
lower | 轉換為小寫 |
first | 輸出陣列的第一個元素 |
last | 輸出陣列的最後一個元素 |
default | 預設值 |
raw | 不使用(預設)轉義 |
Assign.php
<?php namespace app\test\controller; use think\Controller; define('AAA','this is define'); class Assign extends Controller{ public function index(){ $name='Sentiment'; $time=time(); $this->assign('name',$name); $this->assign('time',$time); return $this->fetch(); } }
index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Assign Test</title> </head> <body> this is assign/index.html<br> {$name|md5}<br> //md5('Sentiment') {$name|upper|substr=0,3}<br> //substr(upper('Sentiment')) {$time|date='Y-m-d H:i'}<br> //時間 </body> </html>
原樣輸出
加上{literal}後,{$name}就不會被解析,而是原樣輸出
{literal} Hello,{$name}! {/literal}
模板輸出
單行註釋
格式:
{/* 註釋內容 */ } 或 {// 註釋內容 }
例如
{// 這是模板註釋內容 }
注:{
和註釋標記之間不能有空格。
多行註釋
支援多行註釋,例如:
{/* 這是模板 註釋內容*/ }
模板註釋支援多行,模板註釋在生成編譯快取檔案後會自動刪除,這一點和Html的註釋不同。
模板佈局
全域性配置方式
在template.php
中,開啟layout_on
** 引數(預設不開啟),並且設定佈局入口檔名**layout_name
(預設為layout)。(assign為我的view目錄下的檔案,根據自己情況修改或不加)
'layout_on' => true, 'layout_name' => 'assign/layout',
在不開啟layout_on
佈局模板之前,會直接渲染 application/test/view/assign/index.html
模板檔案,開啟之後,首先會渲染application/test/view/layout.html
** 模板,佈局模板的寫法和其他模板的寫法類似,本身也可以支援所有的模板標籤以及包含檔案,區別在於有一個特定的輸出替換變數**{__CONTENT__}
,例如,下面是一個典型的layout.html模板的寫法:
{include file="public/header" /} {__CONTENT__} {include file="public/footer" /}
在view/assign/下,新建layout.html,包含的是see/index.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>a Test</title> </head> <body> {include file="see/index" /}<br> {__CONTENT__} {include file="see/index" /}<br> </body> </html>
原本的assign/index.html把html標籤去掉即可
{$name|md5}<br> {$name|upper|substr=0,3}<br> {$time|date='Y-m-d H:i'}<br>
訪問後{CONTENT}部分自動替換成了index.html內容
這裡的{CONTENT}是預設的也可以透過修改配置來定義
'layout_item' => '{__REPLACE__}'
這裡透過配置檔案定義的是全域性配置,若某個檔案不想使用該配置,則可以在html檔案中加入{__NOLAYOUT__}
來取消本檔案的全域性配置
{__NOLAYOUT__} //加上後就不會被解析了 {$name|md5}<br> {$name|upper|substr=0,3}<br> {$time|date='Y-m-d H:i'}<br>
模板標籤方式
直接在模板檔案中指定佈局模板即可(前邊的layout_on設定需要關閉)
{//__NOLAYOUT__} {layout name="assign/layout" /} {$name|md5}<br> {$name|upper|substr=0,3}<br> {$time|date='Y-m-d H:i'}<br>
若需要使用其他模板佈局(假設要用lay.html),直接修改標籤即可
{//__NOLAYOUT__} {layout name="assign/lay" /} {$name|md5}<br> {$name|upper|substr=0,3}<br> {$time|date='Y-m-d H:i'}<br>
動態佈局
也不需要設定layout_on
,加上$this->view->engine->layout(true);
即可
<?php namespace app\test\controller; use think\Controller; define('AAA','this is define'); class Assign extends Controller{ public function index(){ $name='Sentiment'; $time=time(); $this->assign('name',$name); $this->assign('time',$time); $this->view->engine->layout(true); //在這裡在這裡 return $this->fetch(); } }
模板繼承
透過{block} {/block}標籤,實現繼承
在view/assign/下,新建base.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>base</title> </head> <body> {block name="header"} <div style= "width:10%; height:30px; background-color:yellow;">this is header</div> {/block}<br> {block name="footer"} <div style= "width:10%; height:30px; background-color:green;">this is footer</div> {/block}<br> </body> </html>
view/assign/index.html
透過extend繼承{extend name="assign/base" /}
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> {extend name="assign/base" /} </body> </html>
如果在子類中實現了與父類中同樣的模板,則以子類中的內容顯示,若此時想同時顯示父類中的內容則可以透過{block}實現
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> {extend name="assign/base" /} {block name="header"}{__block__} //在這裡 在這裡 <div style= "width:10%; height:30px; background-color:red;">this is header</div> {/block}<br> {block name="footer"} <div style= "width:10%; height:30px; background-color:blue;">this is footer</div> {/block}<br> </body> </html>
包含檔案
在模板佈局中已經用到過了就不多解釋了
{include file="see/index" /}
內建標籤
標籤名 | 作用 | 包含屬性 |
---|---|---|
include | 包含外部模板檔案(閉合) | file |
load | 匯入資原始檔(閉合 包括js css import別名) | file,href,type,value,basepath |
volist | 迴圈陣列資料輸出 | name,id,offset,length,key,mod |
foreach | 陣列或物件遍歷輸出 | name,item,key |
for | For迴圈資料輸出 | name,from,to,before,step |
switch | 分支判斷輸出 | name |
case | 分支判斷輸出(必須和switch配套使用) | value,break |
default | 預設情況輸出(閉合 必須和switch配套使用) | 無 |
compare | 比較輸出(包括eq neq lt gt egt elt heq nheq等別名) | name,value,type |
range | 範圍判斷輸出(包括in notin between notbetween別名) | name,value,type |
present | 判斷是否賦值 | name |
notpresent | 判斷是否尚未賦值 | name |
empty | 判斷資料是否為空 | name |
notempty | 判斷資料是否不為空 | name |
defined | 判斷常量是否定義 | name |
notdefined | 判斷常量是否未定義 | name |
define | 常量定義(閉合) | name,value |
assign | 變數賦值(閉合) | name,value |
if | 條件判斷輸出 | condition |
elseif | 條件判斷輸出(閉合 必須和if標籤配套使用) | condition |
else | 條件不成立輸出(閉合 可用於其他標籤) | 無 |
php | 使用php程式碼 | 無 |
volist
這裡以資料庫內容舉例,模板類獲取資料庫所有內容(資料庫—>模板類有說過)
<?php namespace app\test\controller; use think\Controller; use app\test\model\User as UserModel; class Assign extends Controller{ public function index(){ $name=UserModel::all(); $this->assign('name',$name); return $this->fetch(); } }
assign/index.html
"name"為assign的值,根據變數進行修改
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> {volist name="name" id="vo"} {$vo.id}====>{$vo.name}<br/> {/volist} </body> </html>
可以加上offset="0" length="1"
,定義獲取資料的個數
{volist name="name" id="vo" offset="0" length="1"} {$vo.id}====>{$vo.name}<br/> {/volist}
foreach
實現結果同上
{foreach $name as $vo} {$vo.id}====>{$vo.name}<br/> {/foreach}
for
{for start="開始值" end="結束值" comparison="用於比較,預設值是<" step="步長" name="迴圈變數名"} {/for}
迴圈輸出1-10
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> {for start="1" end="10"} {$i} {/for} </body> </html>
php
執行php語句
{php} echo 'hi Sentiment'; {/php}
路由
靜態
Route::get('unserialize', 'unserialize/unserialize');
訪問unserialize後,便會自動跳轉到unserialize/unserialize介面
動態
Route::get('route/:id','test/Index/index');
index.php
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index(){ dump(Request::route()); } }
id為我們動態輸入的值,修改id後返回資訊也會動態變化
請求
請求物件
1.當控制器繼承了控制器基類時,會自動被注入 Request 請求物件的功能
<?php namespace app\test\controller; use think\Controller; class Index extends Controller{ public function index(){ return $this->request->param('name'); } }
2.不繼承控制器基類(操作方法注入)
無論是否繼承系統的控制器基類,都可以使用操作方法注入。
<?php namespace app\test\controller; use think\Request; class Index { public function index(Request $request){ return $request->param('name'); } }
跟1
傳參方式一樣
3、構造方法注入
<?php namespace app\test\controller; use think\Request; class Index { public function __construct(Request $request) { $this->request = $request; } public function index(){ return $this->request->param('name'); } }
4、Facade呼叫(無依賴注入)
在沒有使用依賴注入的場合,可以透過Facade
機制來靜態呼叫請求物件的方法(注意use
引入的類庫區別)。
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index(){ return Request::param('name'); } }
5、助手函式(有無繼承都可)
為了簡化呼叫,系統還提供了request
助手函式,可以在任何需要的時候直接呼叫當前請求物件。
<?php namespace app\test\controller; class Index { public function index() { return request()->param('name'); } }
請求資訊
Request
物件支援獲取當前的請求資訊,包括:
方法 | 含義 |
---|---|
host | 當前訪問域名或者IP |
scheme | 當前訪問協議 |
port | 當前訪問的埠 |
remotePort | 當前請求的REMOTE_PORT |
protocol | 當前請求的SERVER_PROTOCOL |
contentType | 當前請求的CONTENT_TYPE |
domain | 當前包含協議的域名 |
subDomain | 當前訪問的子域名 |
panDomain | 當前訪問的泛域名 |
rootDomain | 當前訪問的根域名(V5.1.6+ ) |
url | 當前完整URL |
baseUrl | 當前URL(不含QUERY_STRING) |
query | 當前請求的QUERY_STRING引數 |
baseFile | 當前執行的檔案 |
root | URL訪問根地址 |
rootUrl | URL訪問根目錄 |
pathinfo | 當前請求URL的pathinfo資訊(含URL字尾) |
path | 請求URL的pathinfo資訊(不含URL字尾) |
ext | 當前URL的訪問字尾 |
time | 獲取當前請求的時間 |
type | 當前請求的資源型別 |
method | 當前請求型別 |
對於上面的這些請求方法,一般呼叫無需任何引數,但某些方法可以傳入true
引數,表示獲取帶域名的完整地址,例如:
use think\facade\Request; // 獲取完整URL地址 不帶域名 Request::url(); // 獲取完整URL地址 包含域名 Request::url(true); // 獲取當前URL(不含QUERY_STRING) 不帶域名 Request::baseFile(); // 獲取當前URL(不含QUERY_STRING) 包含域名 Request::baseFile(true); // 獲取URL訪問根地址 不帶域名 Request::root(); // 獲取URL訪問根地址 包含域名 Request::root(true);
獲取完整URL,不帶域名
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { return Request::url(); } }
請求變數
可以透過Request
物件完成全域性輸入變數的檢測、獲取和安全過濾,支援包括$_GET
、$_POST
、$_REQUEST
、$_SERVER
、$_SESSION
、$_COOKIE
、$_ENV
等系統變數,以及檔案上傳資訊。(所有示例程式碼均使用Facade
方式)
use think\facade\Request;
1、使用 has() 方法,可以檢測全域性變數是否已經設定
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { dump(Request::has('name','get')); dump(Request::has('id','post')); } }
2、變數獲取
變數獲取使用\think\Request
類的如下方法及引數:
變數型別方法('變數名/變數修飾符','預設值','過濾方法')
變數型別方法包括:
方法 | 描述 |
---|---|
param | 獲取當前請求的變數 |
get | 獲取 $_GET 變數 |
post | 獲取 $_POST 變數 |
put | 獲取 PUT 變數 |
delete | 獲取 DELETE 變數 |
session | 獲取 $_SESSION 變數 |
cookie | 獲取 $_COOKIE 變數 |
request | 獲取 $_REQUEST 變數 |
server | 獲取 $_SERVER 變數 |
env | 獲取 $_ENV 變數 |
route | 獲取 路由(包括PATHINFO) 變數 |
file | 獲取 $_FILES 變數 |
獲取當前強求變數
// 獲取當前請求的name變數(過濾) Request::param('name'); // 獲取當前請求的所有變數(過濾) Request::param(); // 獲取當前請求的所有變數(原始資料、不過濾) Request::param(false); // 獲取當前請求的所有變數(包含上傳檔案、過濾) Request::param(true);
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { dump(Request::param()); } }
3、變數過濾
框架預設沒有設定任何全域性過濾規則,可以在應用配置檔案中設定全域性的過濾規則:
# config/app.php // 預設全域性過濾方法 用逗號分隔多個 'default_filter' => 'htmlspecialchars', 如果設定過濾方法,上傳變數資訊會獲取不到 # 單個設定 dump(Request::param('name','','htmlspecialchars'));
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { dump(Request::param('name','','htmlspecialchars')); } }
php7.3沒成功,換成了7.4
4、獲取部分變數(only)
只獲取當前請求的name變數
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { // 只獲取當前請求的name變數 dump(Request::only('name')); //陣列形式 //dump(Request::only(['name'])); } }
except排除某些變數後獲取
dump(Request::except('id')); //陣列形式 dump(Request::except(['id']));
5、預設值
Request::get('name'); // 返回值為null Request::get('name',''); // 返回值為空字串 Request::get('name','default'); // 返回值為default
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { dump(Request::param('name','Sentiment')); dump(Request::param('name')); dump(Request::param('name','default')); } }
6、變數修飾符
Request::變數型別('變數名/修飾符');
/s(字串) /d(整型) /b(布林) /a(陣列) /f(浮點)
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { dump(Request::param('name/s')); dump(Request::param('name/d')); dump(Request::param('name/a')); } }
7、路由獲取
//test/controller/index <?php namespace app\test\controller; use think\facade\Request; class Index { public function index($id) { dump(Request::route()); } } //route/route.php Route::get('route/:id','test/Index/index');
8、助手函式
為了簡化使用,還可以使用系統提供的input
助手函式完成上述大部分功能。
- 判斷變數是否定義
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { //get dump(input('?get.name')); //post dump(input('?post.name')); } }
- 獲取PARAM引數
dump(input('param.name')); // 獲取單個引數 dump(input('param.')); // 獲取全部引數 // 下面是等效的 dump(input('name')); dump(input(''));
- 獲取GET引數
// 獲取單個變數 dump(input('get.id')); // 使用過濾方法獲取 預設為空字串 dump(input('get.name')); // 獲取全部變數 dump(input('get.'));
- 使用過濾方法
dump(input('get.name','','htmlspecialchars')); // 獲取get變數 並用htmlspecialchars函式過濾 dump(input('username','','strip_tags')); // 獲取param變數 並用strip_tags函式過濾 dump(input('post.name','','org\Filter::safeHtml')); // 獲取post變數 並用org\Filter類的safeHtml方法過濾
- 使用變數修飾符
input('get.id/d'); input('post.name/s'); input('post.ids/a');
HTTP資訊
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { $info = Request::header(); dump($info); dump($info['host']); dump($info['user-agent']); } }
偽靜態
URL偽靜態通常是為了滿足更好的SEO效果,ThinkPHP支援偽靜態URL設定,可以透過設定url_html_suffix
引數隨意在URL的最後增加你想要的靜態字尾,而不會影響當前操作的正常執行。
可以透過ext()方法獲取字尾
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { return Request::ext(); } }
當訪問index.pdf後會報錯,但訪問index.html則不會
這是因為在配置檔案中設定的偽靜態為html,若想用pdf,透過|
分割加上即可
'url_html_suffix' => 'html|pdf',
在不該設定的情況下,使用 url::build() 獲取當前完整 url,得到預設字尾為 .html
<?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { return \think\facade\Url::build(); } }
若不想使用偽靜態關閉即可
'url_html_suffix' => false,
引數繫結
1、預設引數
<?php namespace app\test\controller; class Index { public function index($name='Sentiment',$id=1) { return 'name:'.$name.'<br>'.'id:'.$id; } }
2、成對解析,可以換順序
// URL引數方式 0 按名稱成對解析 1 按順序解析 'url_param_type' => 0,
請求快取
全域性快取
// 是否開啟請求快取 true自動快取 支援設定請求快取規則 'request_cache' => false, // 請求快取有效期,建議3600,時間太短沒有意義 'request_cache_expire' => null, // 全域性請求快取排除規則 'request_cache_except' => [],
開啟快取後,第二次訪問時,會自動獲取請求快取的資料響應輸出,併傳送304狀態碼
單獨快取
//route/route.php Route::get('route/:id','test/Index/index')->cache(3600); //test/controller/index.php <?php namespace app\test\controller; use think\facade\Request; class Index { public function index() { dump(Request::param()); dump(Request::route()); } }
重新整理一次後狀態碼變成304,這時就已經快取了,當我改變index.php的內容後,訪問/route/777仍然是這個介面
響應
響應(Response
)物件用於動態響應客戶端請求,控制傳送給使用者的資訊。通常用於輸出資料給客戶端或者瀏覽器。由think\Response
類或者子類完成。
響應引數
響應輸出,包括 return(),json(),view()
<?php namespace app\test\controller; class Index { public function response(){ return response('index','201'); //return response('index')->code('201'); //設定頭資訊 //return response('index')->code('201')->header(['Cache-control' => 'no-cache,must-revalidate']); sh } }
重定向
redirect() 方法頁面重定向
<?php namespace app\test\controller; class Index { public function response(){ return redirect('http://sentiment1.top'); } }
站內重定向,直接輸入路由地址或相對地址即可
return redirect('/index/index/hello/name/Sentiment'); return redirect('hello')->params(['name'=>'Sentiment']); return redirect('hello',['name'=>'Sentiment']);
檔案下載
文字檔案和圖片檔案都可以使用 download() 方法下載
<?php namespace app\test\controller; class Index { public function down(){ $data='this is test'; return download($data,'test.txt',true); } }
訪問/test/index/down後便可下載test.txt,內容為this is test
相關文章
- 初探快應用2018-10-29
- 函式計算——應用初探2020-12-30函式
- webpack 構建多頁面應用——初探2018-12-19Web
- 初探webpack之單應用多端構建2023-12-02Web
- 多執行緒應用初探(一)----(概念,安全)2019-04-08執行緒
- 大語言模型的應用探索—AI Agent初探!2024-07-08模型AI
- ThinkPHP5.1 小計2019-08-15PHP
- 應用部署初探:微服務的3大部署模式2023-02-10微服務模式
- 應用部署初探:6個保障安全的最佳實踐2023-02-20
- 基於阿里雲 ASK 的 Istio 微服務應用部署初探2022-06-10阿里微服務
- 應用部署初探:3個主要階段、4種常見模式2023-02-01模式
- 元宇宙系列白皮書:健康醫療行業應用初探(附下載)2022-05-20元宇宙行業
- Arthas 初探--安裝初步適用2020-09-01
- Wasm在即時通訊IM場景下的Web端應用效能提升初探2024-11-22ASMWeb
- 響應式程式設計庫RxJava初探2021-01-24程式設計RxJava
- 基於IM場景下的Wasm初探:提升Web應用效能|得物技術2024-11-05ASMWeb
- ThinkPHP5.1 Excel 表的匯入匯出操作 (PHPExcel)2019-05-09PHPExcel
- LangChain初探:為你的AI應用之旅導航2024-03-01LangChain
- thinkphp5.1原始碼閱讀與學習(一、路由解析)2021-02-20PHP原始碼路由
- ThinkPHP5.1 中的資料庫遷移和資料填充2020-01-11PHP資料庫
- thinkphp5.1原始碼閱讀與學習(框架初始化)2021-02-20PHP原始碼框架
- Puppeteer 初探2019-02-16
- gRPC 初探2019-02-16RPC
- ## RATreeView 初探2018-11-12View
- 初探Firewalld2019-01-11
- Serverless初探2019-01-09Server
- Mobx 初探2019-03-03
- 初探PWA2019-04-14
- 初探TCP2019-01-21TCP
- 初探 BaconJS2018-08-13JS
- 初探 TypeScript2018-07-03TypeScript
- ECharts 初探2018-05-15Echarts
- Quantum 初探2018-08-20
- 初探 XSS2018-05-15
- 初探canvas2018-06-27Canvas
- puppeteer初探2018-07-25
- Promise初探2018-08-07Promise
- websoctet初探2018-03-16Web