Thinkphp5.1應用初探

SecIN發表於2022-10-08

直接審計tp的話應該會很有難度,不妨先了解一些tp內建規則和用法,便於在後續的審計中更好的理解程式碼含義。

原始碼下載連結

ThinkPHP5.1 開發手冊

安裝

沒有composer可以去下載,傻瓜式安裝即可Composer (getcomposer.org)

使用composer安裝

composer create-project topthink/think tp

啟動服務

cd tp php think run

然後就可以在瀏覽器中訪問

http://localhost:8000

搭建成功

wKg0C2JeviAUGrMAABfbxtCDSc342.png

目錄結構

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為字尾;
  • 類的檔名均以名稱空間定義,並且名稱空間的路徑和類庫檔案所在路徑一致;
  • 類名和類檔名保持一致,統一採用駝峰法命名(首字母大寫);

函式和類、屬性命名

  • 類的命名採用駝峰法,並且首字母大寫,例如 UserUserType,預設不需要新增字尾,例如UserController應該直接命名為User
  • 函式的命名使用小寫字母和下劃線(小寫字母開頭)的方式,例如 get_client_ip
  • 方法的命名使用駝峰法,並且首字母小寫,例如 getUserName
  • 屬性的命名使用駝峰法,並且首字母小寫,例如 tableNameinstance
  • 以雙下劃線“__”打頭的函式或方法作為魔法方法,例如 __call__autoload

常量和配置

  • 常量以大寫字母和下劃線命名,例如 APP_PATHTHINK_PATH
  • 配置引數以小寫字母和下劃線命名,例如 url_route_onurl_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

wKg0C2JewqALi9iAACDi9FfNU102.png

wKg0C2JexGAAnY3AAAvtBHmZ54837.png

在url位址列裡面如果不寫模組、控制器和操作名,預設訪問的就是index模組下面的index控制器下面的index操作,可以在config/app.php檔案中進行修改。

wKg0C2JexiAVZQtAACP9fAkPrg521.png

控制器定義

控制器,即 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形式才行

wKg0C2JeyOAZagrAAAe3OgNmR4383.png

渲染輸出

使用 view 輸出模板

方法同名檔案

tp中內建了一個view()方法,它可以找到同模組下的view/控制器同名資料夾(這裡就是test)/與方法同名的檔案.html(定義的是show方法,所以會自動追蹤到show.html)

wKg0C2Jey2ADFtwAABzgrHNlTA929.png

wKg0C2JezSAAwsfAABrJGinL04751.png

根據url解析模式,直接訪問test模組,test控制器,show操作

wKg0C2Jez2AJ2rKAAAnU3sK1dw363.png

不同名檔案

若不是方法同名.html,在view()中加上對應的html檔名即可(`view/同名控制器/引數同名.html)

wKg0C2Je0iAc3VuAAB6WBLnJhU282.png

wKg0C2Je06AQe3NAAAyQxzG6g619.png

資料庫操作

資料庫配置在config/database.php下,資料庫操作分為兩種型別:DB類,模型類

這裡先設定下資料庫名,使用者名稱,密碼,表字首可選我這裡填的think_

wKg0C2Je1iAZvZ4AACOPnhorE450.png

下一步就是建立資料庫了,在think資料庫的think_data表下建立三個欄位

wKg0C2Je2SAC2WSAACMB3i1xyg450.png

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);     } }

訪問方法

wKg0C2Je3WAVQRAABEyL5iTMY585.png

執行成功

wKg0C2Je36AOe98AACTyevia9w926.png

再插入一條

$resault = Db::execute('insert into think_data (id,name,status) values(1,"Tana",1)');

wKg0C2Je5GABnUvAAAT6iTV2l8336.png

更新資料

<?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);     } }

wKg0C2Je7OARwvRAAAUA3fmvtQ771.png

刪除資料

<?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);     } }

wKg0C2Je6uAcMfnAAAPkbyUnvI188.png

查詢資料

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);     } }

wKg0C2Je7ActcAABoZ91v3I794.png

查詢構造器

新增資料

透過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查詢欄位是否(不)是NULLwhereNull/whereNotNull
[NOT] EXISTSEXISTS查詢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表

wKg0C2Je9CAECEAAC2gjHGPw176.png

在test/model下建個think_user模型User,這裡的模型名=表名,所以必須叫User

wKg0C2Je9qAL4UHAAB3lBYdWPo227.png

新增資料

建好模型就開始資料庫操作了,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就沒加,結果一直沒成功)

wKg0C2JeOATu81AAA9XSeDsiI178.png

批次新增

也可以透過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內容及變數值

wKg0C2JeeAWc34AAA2mCZNak667.png

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]);

wKg0C2JfAaAEA0GAAAka7wArDE410.png

檢視過濾

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/>

wKg0C2JfBOATIG1AAA20w3xP0A355.png

初始化中全域性過濾

<?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>

wKg0C2JfDaAX4GfAAAu2j4L9zo458.png

系統變數輸出

{$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}

wKg0C2JfGAS7jJAAAmIBygbc126.png

配置輸出

{$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>

wKg0C2JfICABzZWAABElNObf1I051.png

原樣輸出

加上{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內容

wKg0C2JfKWAYqKOAABkk6OMIm4991.png

這裡的{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>

wKg0C2JfLaAMq8IAAAwMwM72wA040.png

如果在子類中實現了與父類中同樣的模板,則以子類中的內容顯示,若此時想同時顯示父類中的內容則可以透過{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>

wKg0C2JfMWAZxSUAABQKTV88nY289.png

包含檔案

在模板佈局中已經用到過了就不多解釋了

{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
forFor迴圈資料輸出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>

wKg0C2JfNiAAdfHAAAjMfEEhuI397.png

可以加上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>

wKg0C2JfOGAPP63AAAh6YAvdqg993.png

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');     } }

wKg0C2JfQOAYPtoAAAmzU09FU698.png

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當前執行的檔案
rootURL訪問根地址
rootUrlURL訪問根目錄
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();     } }

wKg0C2JfVyADHdcAAAlTAzQylE262.png

請求變數

可以透過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'));     } }

wKg0C2JfWOAYph0AABmtetlU676.png

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());     } }

wKg0C2JfW6AKF9sAABQnNJgB60054.png

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

wKg0C2JfXiAGYmeAAA1p4f1Pk4552.png

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']));     } }

wKg0C2JfYeAcWvoAABPnvVuSU832.png

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'));     } }

wKg0C2JfZKADqAFAABjUFhJxwQ544.png

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'));     } }

wKg0C2JfZuACSDsAABoeDnKUr4546.png

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');

wKg0C2JfbmAAoAABGdFKi94704.png

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'));     } }

wKg0C2JfciAenR4AABa7CiTI7o545.png

  • 獲取PARAM引數
dump(input('param.name')); // 獲取單個引數 dump(input('param.')); // 獲取全部引數 // 下面是等效的 dump(input('name')); dump(input(''));

wKg0C2Jfd2ABGqwAACNJJ7Bvk125.png

  • 獲取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']);     } }

wKg0C2JfeqAOf4OAACbof2QHM242.png

偽靜態

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則不會

wKg0C2JffOAFwMMAAAYZWWqhis573.png

這是因為在配置檔案中設定的偽靜態為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();     } }

wKg0C2Jff2AXBsZAAAeMEDgjM174.png

若不想使用偽靜態關閉即可

'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;     } }

wKg0C2JfgWAKYnZAAAfo4CRI567.png

wKg0C2Jfg2AZPKAAAAiOeDrzw264.png

2、成對解析,可以換順序

wKg0C2JfhSAXma0AAAkA5ngE2A537.png

// 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仍然是這個介面

wKg0C2JfhyAUi53AACZmeOizXs757.png

響應

響應(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     } }

wKg0C2JfiaAd7pxAABX2lpsMc585.png

重定向

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


相關文章