Slim应用的路由和中间件都通过一个PSR 7请求对象来表示当前从你的Web服务器中接收的HTTP请求.这个请求是PSR 7 ServerRequestInterface 接口的实现,你可以通过它去检查和操作请求的方法(method),头部(headers)和主体(body).
怎么获得请求对象
在Slim 3中,PSR 7请求对象作为路由回调的第一个参数已经被注入到你的Slim应用路由中.
<?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
$app = new \Slim\App;
$app->get('/foo', function (ServerRequestInterface $request, ResponseInterface $response) {
// Use the PSR 7 $request object
return $response;
});
$app->run();
在Slim 3中,PSR 7请求对象作为中间件回调的第一个参数已经被注入到你的Slim应用中间件中.
<?php
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
$app = new \Slim\App;
$app->add(function (ServerRequestInterface $request, ResponseInterface $response, callable $next) {
// Use the PSR 7 $request object
return $next($request, $response);
});
// Define app routes...
$app->run();
请求对象方法
任何一个HTTP请求都有以下方法:
* GET
* POST
* PUT
* DELETE
* HEAD
* PATCH
* OPTIONS
你可以通过Request请求对象的方法(getMethod()
)检测HTTP 请求中有的方法:
$method = $request->getMethod();
此外,Slim内置了PSR 7的实现,还提供了一些专有的方法返回 true
或者 false
* $request->isGet()
* $request->isPost()
* $request->isPut()
* $request->isDelete()
* $request->isHead()
* $request->isPatch()
* $request->isOptions()
你还看去伪造或者重载HTTP请求方式。这在一些环境中是非常重要的,比如你需要一个PUT
请求,但是传统的HTTP请求只支持 GET
和POST
.
我们有两种方式去实现伪造HTTP请求方式,你可以把一个_METHOD
参数放在请求的body里面,请求必须使用application/x-www-form-urlencoded
类型(content-type),示例:
POST /path HTTP/1.1
Host: example.com
Content-type: application/x-www-form-urlencoded
Content-length: 22
data=value&_METHOD=PUT
你也可以通过修改HTTP请求方式,通过修改请求头,增加X-Http-Method-Override
,这种方式可以使用任何类型(content-type
),示例:
POST /path HTTP/1.1
Host: example.com
Content-type: application/json
Content-length: 16
X-Http-Method-Override: PUT
{"data":"value"}
修改完之后,你也可以通过PSR 7对象的方法,获取原始的请求方式,方法名:getOriginalMethod()
.
请求URI
任何一个HTTP请求都有一个URI标识请求应用的资源,请求URI有几个部分组成:
* Scheme (e.g. http or https) //协议
* Host (e.g. example.com) //域名host
* Port (e.g. 80 or 443) //端口
* Path (e.g. /users/1) //路径
* Query string (e.g. sort=created&dir=asc) //请求参数
你可以通过PSR 7请求对象的方法 getUri()
获取PSR 7请求对象URI:
$uri = $request->getUri();
PSR 7请求对象URI是PSR 7自身的一个对象,它提供了一些方法去检查请求url的各个部分:
* getScheme()
* getHost()
* getPort()
* getPath()
* getBasePath()
* getQuery() (returns string)
* getQueryParams() (returns associative array)
如果你的Slim应用的前端控制器是在服务器根目录下的子目录里面,你可以通过 getBasePath() 获取到一个相当于服务器目录的路径。如果你的Slim应用是在服务器根目录下面,则返回空字符串
请求头
任何一个HTTP请求都有请求头,请求头描述了一个HTTP请求,但是不可以在请求主体中看到,Slim 的PSR 7请求对象提供了一些方法查看请求头。
获取请求头所有信息
你可以通过PSR 7 请求对象的方法 getHeaders()
获得HTTP请求的请求头的所有信息,结果将以数组形式返回.结果数组键名是请求头的名,值是以数字索引数组的形式返回.
$headers = $request->getHeaders();
foreach ($headers as $name => $values) {
echo $name . ": " . implode(", ", $values);
}
示例:
Array
(
[Host] => Array
(
[0] => z.slim.com
)
[HTTP_CONNECTION] => Array
(
[0] => keep-alive
)
[HTTP_CACHE_CONTROL] => Array
(
[0] => max-age=0
)
[HTTP_ACCEPT] => Array
(
[0] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
)
[HTTP_USER_AGENT] => Array
(
[0] => Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.152 Safari/537.36
)
[HTTP_ACCEPT_ENCODING] => Array
(
[0] => gzip, deflate, sdch
)
[HTTP_ACCEPT_LANGUAGE] => Array
(
[0] => zh-CN,zh;q=0.8
)
)
获取请求头中的一条信息
你可以通过PSR 7请求对象的方法 getHeader()
获得某一个请求头的值,它会返回一个由相对应的请求头的名称的值组成的数组.但是注意:一个请求头名称有可能有好多条值.
$headerValueArray = $request->getHeader('Accept');
示例:
Array
(
[0] => text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
)
当然你也可以通过PSR 7请求对象的方法 getHeaderLine($name)
选择以逗号分隔的字符串形式返回,不同于方法 getHeader()
,此方法将值以逗号分隔的字符串形式返回:
$headerValueString = $request->getHeaderLine('Accept');
示例:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
检测请求头
我们也可以通过 PSR 7请求对象的方法 hasHeader()
,判断是否有某个请求头
if ($request->hasHeader('Accept')) {
// Do something
}
请求正文
任何一条HTTP请求都有请求正文,如果你的Slim应用需要使用JSON 或则 XML 形式的数据,你可以通过 PSR 7请求对象的方法 getParsedBody()
把请求正文解析成原生的PHP格式的.Slim可以解析 JSON,XML,URL编码格式的数据
$parsedBody = $request->getParsedBody();
PHP原生格式化方法:
JSON数据使用方法 json_decode($input,true) 解析成数组
XML通过方法 simplexml_load_string($input) 解析成一个 SimpleXMLElement对象
URL编码的通过方法 parse_str($input) 解析成数组
Slim PSR 7请求对象表示HTTP 请求正文是作为一个 \Psr\Http\Message\StreamInterface
接口的实现,你可以通过 StreamInterface在PSR 7请求对象中的实现方法 getBody()
获得HTTP 请求正文.getBody()
方法是当你请求携带的数据比较大或者未知的时候首选的方法:
$body = $request->getBody();
返回的结果,可以通过\Psr\Http\Message\StreamInterface
实现提供了下面的方法去读取和迭代PHP底层的资源:
* getSize()
* tell()
* eof()
* isSeekable()
* seek()
* rewind()
* isWriteable()
* write($string)
* isReadable()
* read($string)
* getContents()
* getMetadata($key = null)
一些请求帮助函数
Slim的PSR 7请求提供了一些特殊的方法,去帮助你检查特殊的HTTP请求
检测XHR请求(个人理解是Ajax请求)
你可以通过请求对象的 isXhr()
方法检测XHR请求,这个方法的作用主要是检测X-Requested-With
请求头的存在以及确保这个请求头的值是XMLHttpRequest
。
POST /path HTTP/1.1
Host: example.com
Content-type: application/x-www-form-urlencoded
Content-length: 7
X-Requested-With: XMLHttpRequest
foo=bar
示例:
if ($request->isXhr()) {
// Do something
}
Content type
你可以通过通过请求对象的 getContentType()
方法获得HTTP 请求的Content type,这个函数返回客户端那边传过来的Content type的值
$contentType = $request->getContentType();
示例:
application/x-www-form-urlencoded
Media Type
也许你要的不是 Content type的值,你只是想要 Media Type 的值,你可以通过通过请求对象的 getMediaType()
方法获得HTTP 请求的Media Type
$mediaType = $request->getMediaType();
你也可以通过方法getMediaTypeParams()
获得数组形式的参数值
$mediaParams = $request->getMediaTypeParams();
Character Set
最常用的一个Media类型参数就是字符串了,Slim请求对象提供了一个专用的方法去检索这个值
$charset = $request->getContentCharset();
Content 长度
你可以通过方法 getContentLength()
获取请求值的长度
$length = $request->getContentLength();
路由对象
有时候,在中间件里面需要参数
在这个示例里面我们首先验证用户是否登陆,其次验证用户是否有权限查看视频
$app->get('/course/{id}', Video::class.":watch")->add(Permission::class)->add(Auth::class);
//.. In the Permission Class's Invoke
/** @var $route \Slim\Route */
$route = $request->getAttribute('route');
$courseId = $route->getArgument('id');
文档翻译的并不是很专业,仅供个人学习作用,建议看官方文档。
如有兴趣,请看下一篇 SLIM 3 文档(八)-响应(RESPONSE)6)