請求對象
當前的請求對象由think\Request
類負責,該類不需要單獨實例化調用,通常使用依賴注入即可。在其它場合則可以使用think\facade\Request
靜態類操作。
項目里面應該使用app\Request
對象,該對象繼承了系統的think\Request
對象,但可以增加自定義方法或者覆蓋已有方法。項目里面已經在provider.php
中進行了定義,所以你仍然可以和之前一樣直接使用容器和靜態代理操作請求對象。
構造方法注入
一般適用于沒有繼承系統的控制器類的情況。
<?phpnamespace app\index\controller;use think\Request;class Index
{/*** @var \think\Request Request實例*/protected $request;/*** 構造方法* @param Request $request Request對象* @access public*/public function __construct(Request $request){$this->request = $request;}public function index(){return $this->request->param('name');}
}
操作方法注入
另外一種選擇是在每個方法中使用依賴注入。
<?phpnamespace app\index\controller;use think\Request;class Index
{public function index(Request $request){return $request->param('name');}
}
無論是否繼承系統的控制器基類,都可以使用操作方法注入。
靜態調用
在沒有使用依賴注入的場合,可以通過Facade
機制來靜態調用請求對象的方法(注意use
引入的類庫區別)。
<?phpnamespace app\index\controller;use think\facade\Request;class Index
{public function index(){return Request::param('name');}
}
該方法也同樣適用于依賴注入無法使用的場合。
助手函數
為了簡化調用,系統還提供了request
助手函數,可以在任何需要的時候直接調用當前請求對象。
<?phpnamespace app\index\controller;class Index
{public function index(){return request()->param('name');}
}
自定義請求對象
你可以在項目里面自定義Request對象,修改已有的方法或者增加新的方法,默認已經在項目里面為你準備了app\Request
類,你只需要直接修改該類就可以為你的項目單獨自定義請求對象。
自定義請求對象不支持為多應用的某個應用自定義,只能是全局自定義,如果你需要為某個應用定義不同的請求對象,可以在入口文件里面修改。例如:
// 執行HTTP應用并響應
$request = new app\common\Request();
$http = (new App())->http;
$response = $http->run($request);
$response->send();
$http->end($response);
請求信息
1. Request對象支持全局變量的檢測、獲取和安全過濾,支持$_GET、$_POST...等;
2. 為了方便演示,這里一律使用Facade的靜態調用模式;
3. 使用has()方法,可以檢測全局變量是否已經設置:
Request::has('id', 'get');
Request::has('username', 'post');
它是以get的方式不存在,還是以post方式不存在呢?
然后顯示以get方式不存在。
如果改成name了呢
就變成了true
4. Request支持的所有變量類型方法,如下表:
5. param()變量方法是自動識別GET、POST等的當前請求,推薦使用;
//獲取請求為name的值,過濾
Request::param('name');//獲取所有請求的變量,以數組形式,過濾
Request::param();//獲取所有請求的變量(原始變量),不包含上傳變量,不過濾
Request::param(false);//獲取部分變量
Request::param(['name','age']);
怎么取出name的值呢,如下
如果param()不輸入指定的值,就是獲取所有值。
獲取部分值:
6.默認情況下,并沒有配置字符過濾器,可在app\Request.php配置;
protected $filter = ['htmlspecialchars'];
設置字符過濾(轉義),第二個為什么不轉移呢,是由于上面所說的
?//獲取所有請求的變量(原始變量),不包含上傳變量,不過濾
Request::param(false);
7.如果沒有設置字符過濾器,或者局部用別的字符過濾器,可以通過第三參數;
Request::param('name','','htmlspecialchars');Request::param('name','','strip_tags,strtolower');
如果設置了全局過濾器,那么這個局部過濾器就會把全局過濾器給替換掉。
如果兩個都想要的話,就加個逗號。
8.如果設置了全局字符過濾器,但又不想某個局部使用,可以只用null參數;
Request::param('name','',null)
9.如果獲取不到值,支持請求的變量設置一個默認值;
Request::param('name','默認值');
10.如果采用的是路由URL,也可以獲取到變量,但param::get()不支持路由變量;
Request::param('id');Request::route('id');Request::get('id'); //路由參數,get獲取不到
使用Request::get("id"),獲取不到。
使用Route呢?
就可以獲取。
那Request::get("id")可以獲取什么呢?只能獲取''?''后面的值
(一個就是獲取路由的id,一個是獲取網址的id)不管哪種id都可以通過param獲取。
11.使用only()方法,可以獲取指定的變量,也可以設置默認值;
Request::only(['id','name']);Request::only(['id'=>1,'name'=>'默認值']);
12.使用only()方法,默認是param變量,可以在第二參數設置GET、POST等;
Request::only(['id','name'],'post');
13.相反的except()方法,就是排除指定的變量;
Request::except('id,name');Request::except(['id','name']);Request::except(['id'=>1,'name'=>'默認值']);Request::except(['id','name'],'post');
14.使用變量修飾符,可以將參數強制轉換成指定的類型;
15./s(字符串)、/d(整型)、/b(布爾)、/a(數組)、/f(浮點);
Request::param('id/d');
14.15傳入的age目前只是字符串。
加個/d的話就是強制類型整型。
把網址改成abc之后就會變成0
助手函數
1.為了簡化操作,Request對象提供了助手函數;
input('?get.id'); //判斷get下的id是否存在
input('?post.name'); //判斷post下的name是否存在
input('param.name'); //獲取param下的name值
input('param.name', '默認值'); //默認值
input('param.name', '', 'htmlspecialchars'); //過濾器
input('param.id/d'); //設置強制轉換
===================================================================
Request
對象支持獲取當前的請求信息,包括:
方法 | 含義 |
---|---|
host | 當前訪問域名或者IP |
scheme | 當前訪問協議 |
port | 當前訪問的端口 |
remotePort | 當前請求的REMOTE_PORT |
protocol | 當前請求的SERVER_PROTOCOL |
contentType | 當前請求的CONTENT_TYPE |
domain | 當前包含協議的域名 |
subDomain | 當前訪問的子域名 |
panDomain | 當前訪問的泛域名 |
rootDomain | 當前訪問的根域名 |
url | 當前完整URL |
baseUrl | 當前URL(不含QUERY_STRING) |
query | 當前請求的QUERY_STRING參數 |
baseFile | 當前執行的文件 |
root | URL訪問根地址 |
rootUrl | URL訪問根目錄 |
pathinfo | 當前請求URL的pathinfo信息(含URL后綴) |
ext | 當前URL的訪問后綴 |
time | 獲取當前請求的時間 |
type | 當前請求的資源類型 |
method | 當前請求類型 |
rule | 當前請求的路由對象實例 |
對于上面的這些請求方法,一般調用無需任何參數,但某些方法可以傳入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);
注意domain
方法的值本身就包含協議和域名
獲取當前控制器/操作
可以通過請求對象獲取當前請求的控制器/操作名。
方法 | 含義 |
---|---|
controller | 當前請求的控制器名 |
action | 當前請求的操作名 |
獲取當前控制器
Request::controller();
返回的是控制器的駝峰形式(首字母大寫),和控制器類名保持一致(不含后綴)。
如果需要返回小寫可以使用
Request::controller(true);
如果要返回小寫+下劃線的方式,可以使用
parse_name(Request::controller());
獲取當前操作
Request::action();
返回的是當前操作方法的實際名稱,如果需要返回小寫可以使用
Request::action(true);
如果要返回小寫+下劃線的方式,可以使用
parse_name(Request::action());
如果使用了多應用模式,可以通過下面的方法來獲取當前應用
app('http')->getName();
輸入變量
可以通過Request
對象完成全局輸入變量的檢測、獲取和安全過濾,支持包括$_GET
、$_POST
、$_REQUEST
、$_SERVER
、$_SESSION
、$_COOKIE
、$_ENV
等系統變量,以及文件上傳信息。
為了方便說明,本篇內容的所有示例代碼均使用Facade
方式,因此需要首先引入
use think\facade\Request;
檢測變量是否設置
可以使用has
方法來檢測一個變量參數是否設置,如下:
Request::has('id','get');
Request::has('name','post');
變量檢測可以支持所有支持的系統變量,包括get/post/put/request/cookie/server/session/env/file
。
變量獲取
變量獲取使用\think\Request
類的如下方法及參數:
變量類型方法('變量名/變量修飾符','默認值','過濾方法')
變量類型方法包括:
方法 | 描述 |
---|---|
param | 獲取當前請求的變量 |
get | 獲取 $_GET 變量 |
post | 獲取 $_POST 變量 |
put | 獲取 PUT 變量 |
delete | 獲取 DELETE 變量 |
session | 獲取 SESSION 變量 |
cookie | 獲取 $_COOKIE 變量 |
request | 獲取 $_REQUEST 變量 |
server | 獲取 $_SERVER 變量 |
env | 獲取 $_ENV 變量 |
route | 獲取 路由(包括PATHINFO) 變量 |
middleware | 獲取 中間件賦值/傳遞的變量 |
file | 獲取 $_FILES 變量 |
all?V6.0.8+ | 獲取包括 $_FILES 變量在內的請求變量,相當于param+file |
獲取PARAM
變量
PARAM
類型變量是框架提供的用于自動識別當前請求的一種變量獲取方式,是系統推薦的獲取請求參數的方法,用法如下:
// 獲取當前請求的name變量
Request::param('name');
// 獲取當前請求的所有變量(經過過濾)
Request::param();
// 獲取當前請求未經過濾的所有變量
Request::param(false);
// 獲取部分變量
Request::param(['name', 'email']);
param
方法會把當前請求類型的參數和路由變量以及GET請求合并,并且路由變量是優先的。
其它的輸入變量獲取方法和param
方法用法基本一致。
你無法使用get方法獲取路由變量,例如當訪問地址是
http://localhost/index.php/index/index/hello/name/thinkphp
下面的用法是錯誤的
echo Request::get('name'); // 輸出為空
正確的用法是
echo Request::param('name'); // 輸出thinkphp
除了server
和env
方法的變量名不區分大小寫(會自動轉為大寫后獲取),其它變量名區分大小寫。
默認值
獲取輸入變量的時候,可以支持默認值,例如當URL中不包含$_GET['name']
的時候,使用下面的方式輸出的結果比較。
Request::get('name'); // 返回值為null
Request::get('name',''); // 返回值為空字符串
Request::get('name','default'); // 返回值為default
前面提到的方法都支持在第二個參數中傳入默認值的方式。
變量過濾
框架默認沒有設置任何全局過濾規則,你可以在
app\Request
對象中設置filter
全局過濾屬性:
namespace app;class Request extends \think\Request
{protected $filter = ['htmlspecialchars'];
}
也支持使用Request
對象進行全局變量的獲取過濾,過濾方式包括函數、方法過濾,以及PHP內置的Types of filters,我們可以設置全局變量過濾方法,支持設置多個過濾方法,例如:
Request::filter(['strip_tags','htmlspecialchars']),
也可以在獲取變量的時候添加過濾方法,例如:
Request::get('name','','htmlspecialchars'); // 獲取get變量 并用htmlspecialchars函數過濾
Request::param('username','','strip_tags'); // 獲取param變量 并用strip_tags函數過濾
Request::post('name','','org\Filter::safeHtml'); // 獲取post變量 并用org\Filter類的safeHtml方法過濾
如果當前不需要進行任何過濾的話,可以使用
// 獲取get變量 并且不進行任何過濾 即使設置了全局過濾
Request::get('name', '', null);
對于body中提交的json
對象,你無需使用php://input
去獲取,可以直接當做表單提交的數據使用,因為系統已經自動處理過了
獲取部分變量
如果你只需要獲取當前請求的部分參數,可以使用:
// 只獲取當前請求的id和name變量
Request::only(['id','name']);
采用only
方法能夠安全的獲取你需要的變量,避免額外變量影響數據處理和寫入
only
方法可以支持批量設置默認值,如下:
// 設置默認值
Request::only(['id'=>0,'name'=>'']);
表示id
的默認值為0,name
的默認值為空字符串。
默認獲取的是當前請求參數(PARAM
類型變量),如果需要獲取其它類型的參數,可以在第二個參數傳入,例如:
// 只獲取GET請求的id和name變量
Request::only(['id','name'], 'get');
// 等效于
Request::get(['id', 'name']);
// 只獲取POST請求的id和name變量
Request::only(['id','name'], 'post');
// 等效于
Request::post(['id', 'name']);
也支持排除某些變量后獲取,例如
// 排除id和name變量
Request::except(['id','name']);
同樣支持指定變量類型獲取:
// 排除GET請求的id和name變量
Request::except(['id','name'], 'get');
// 排除POST請求的id和name變量
Request::except(['id','name'], 'post');
變量修飾符
支持對變量使用修飾符功能,可以一定程度上簡單過濾變量,更為嚴格的過濾請使用前面提過的變量過濾功能。
用法如下:
Request::變量類型('變量名/修飾符');
支持的變量修飾符,包括:
修飾符 | 作用 |
---|---|
s | 強制轉換為字符串類型 |
d | 強制轉換為整型類型 |
b | 強制轉換為布爾類型 |
a | 強制轉換為數組類型 |
f | 強制轉換為浮點類型 |
下面是一些例子:
Request::get('id/d');
Request::post('name/s');
Request::post('ids/a');
中間件變量
可以在中間件里面設置和獲取請求變量的值,這個值的改變不會影響PARAM
變量的獲取。
<?phpnamespace app\http\middleware;class Check
{public function handle($request, \Closure $next){if ('think' == $request->name) {$request->name = 'ThinkPHP';}return $next($request);}
}
助手函數
為了簡化使用,還可以使用系統提供的input
助手函數完成上述大部分功能。
判斷變量是否定義
input('?get.id');
input('?post.name');
獲取PARAM參數
input('param.name'); // 獲取單個參數
input('param.'); // 獲取全部參數
// 下面是等效的
input('name');
input('');
獲取GET參數
// 獲取單個變量
input('get.id');
// 使用過濾方法獲取 默認為空字符串
input('get.name');
// 獲取全部變量
input('get.');
使用過濾方法
input('get.name','','htmlspecialchars'); // 獲取get變量 并用htmlspecialchars函數過濾
input('username','','strip_tags'); // 獲取param變量 并用strip_tags函數過濾
input('post.name','','org\Filter::safeHtml'); // 獲取post變量 并用org\Filter類的safeHtml方法過濾
使用變量修飾符
input('get.id/d');
input('post.name/s');
input('post.ids/a');
請求類型
1. 有時,我們需要判斷Request的請求類型,比如GET、POST等等;
2. 可以使用method()方法來判斷當前的請求類型,當然,還有很多專用的請求判斷;
判斷GET請求:
判斷是否為POST請求:
3. 使用普通表單提交,通過method()方法獲取類型;
<form action="http://localhost/tp6/public/rely/get" method="post"><input type="text" name="name" value="Lee"><input type="submit" value="提交"></form>return Request::method();
根據這個來POST請求:
使用method方法獲取get還是post請求。
?return Request::method();
上面這個圖片雖然,method='put',但是識別的還是POST。
4. 在表單提交時,我們也可以設置請求類型偽裝,設置隱藏字段_method;
?
根據上面的操作才能變成PUT
5. 而在判斷請求,使用method(true)可以獲取原始請求,否則獲取偽裝請求;
<input type="hidden" name="_method" value="PUT">Request::method(true);
6. 如果想更改請求偽裝變量類型的名稱,可以在app/Request.php中更改;
protected $varMethod = '_m';
7. AJAX/PJAX 偽裝,使用?_ajax=1和?_pjax=1,并使用isAjax()和isPjax();
.../rely?_ajax=1Request::isAjax();
8. 這里需要用isAjax()和isPjax()來判斷,用method無法判斷是否為a(p)jax;
9. 在app.php也可以更改ajax和pjax的名稱;
protected $varAjax = '_a';protected $varPjax = '_p';
HTTP頭信息
1. 使用header()方法可以輸出HTTP頭信息,返回是數組類型,也可單信息獲取;?
Request::header();Request::header('host');