请求
概述
Flight 将 HTTP 请求封装成一个单一的对象,可以通过以下方式访问:
$request = Flight::request();理解
HTTP 请求是理解 HTTP 生命周期的核心方面之一。用户在网页浏览器或 HTTP 客户端上执行一个操作,他们会向你的项目发送一系列头部、主体、URL 等。你可以捕获这些头部(浏览器的语言、他们能处理的压缩类型、用户代理等),并捕获发送到你的 Flight 应用程序的主体和 URL。这些请求对于你的应用程序了解下一步该做什么至关重要。
基本用法
PHP 有几个超级全局变量,包括 $_GET、$_POST、$_REQUEST、$_SERVER、$_FILES 和 $_COOKIE。Flight 将这些抽象成方便的 Collections。你可以将 query、data、cookies 和 files 属性访问为数组或对象。
注意: 强烈不鼓励在你的项目中使用这些超级全局变量,应该通过
request()对象来引用它们。注意:
$_ENV没有可用的抽象。
$_GET
你可以通过 query 属性访问 $_GET 数组:
// GET /search?keyword=something
Flight::route('/search', function(){
$keyword = Flight::request()->query['keyword'];
// 或
$keyword = Flight::request()->query->keyword;
echo "You are searching for: $keyword";
// 使用 $keyword 查询数据库或其他内容
});$_POST
你可以通过 data 属性访问 $_POST 数组:
Flight::route('POST /submit', function(){
$name = Flight::request()->data['name'];
$email = Flight::request()->data['email'];
// 或
$name = Flight::request()->data->name;
$email = Flight::request()->data->email;
echo "You submitted: $name, $email";
// 使用 $name 和 $email 保存到数据库或其他内容
});$_COOKIE
你可以通过 cookies 属性访问 $_COOKIE 数组:
Flight::route('GET /login', function(){
$savedLogin = Flight::request()->cookies['myLoginCookie'];
// 或
$savedLogin = Flight::request()->cookies->myLoginCookie;
// 检查它是否真的保存了,如果是则自动登录
if($savedLogin) {
Flight::redirect('/dashboard');
return;
}
});有关设置新 cookie 值的帮助,请参阅 overclokk/cookie
$_FILES
你可以通过 files 属性访问上传的文件:
// 直接访问 $_FILES 属性。以下是推荐的方法
$uploadedFile = Flight::request()->files['myFile'];
// 或
$uploadedFile = Flight::request()->files->myFile;有关更多信息,请参阅 Uploaded File Handler。
处理文件上传
v3.12.0
你可以使用框架的一些辅助方法来处理文件上传。它基本上归结为从请求中拉取文件数据,并将其移动到新位置。
Flight::route('POST /upload', function(){
// 如果你有一个输入字段如 <input type="file" name="myFile">
$uploadedFileData = Flight::request()->getUploadedFiles();
$uploadedFile = $uploadedFileData['myFile'];
$uploadedFile->moveTo('/path/to/uploads/' . $uploadedFile->getClientFilename());
});如果你有多个文件上传,可以循环遍历它们:
Flight::route('POST /upload', function(){
// 如果你有一个输入字段如 <input type="file" name="myFiles[]">
$uploadedFiles = Flight::request()->getUploadedFiles()['myFiles'];
foreach ($uploadedFiles as $uploadedFile) {
$uploadedFile->moveTo('/path/to/uploads/' . $uploadedFile->getClientFilename());
}
});安全注意: 始终验证和清理用户输入,特别是处理文件上传时。始终验证你允许上传的扩展类型,但你还应该验证文件的“魔术字节”以确保它是用户声称的文件类型。有 文章 和 库 可帮助处理此问题。
请求主体
要获取原始 HTTP 请求主体,例如处理 POST/PUT 请求时,你可以这样做:
Flight::route('POST /users/xml', function(){
$xmlBody = Flight::request()->getBody();
// 处理发送的 XML。
});JSON 主体
如果你收到内容类型为 application/json 的请求,并且示例数据为 {"id": 123},它将从 data 属性可用:
$id = Flight::request()->data->id;请求头部
你可以使用 getHeader() 或 getHeaders() 方法访问请求头部:
// 也许你需要 Authorization 头部
$host = Flight::request()->getHeader('Authorization');
// 或
$host = Flight::request()->header('Authorization');
// 如果你需要获取所有头部
$headers = Flight::request()->getHeaders();
// 或
$headers = Flight::request()->headers();请求方法
你可以使用 method 属性或 getMethod() 方法访问请求方法:
$method = Flight::request()->method; // 实际上由 getMethod() 填充
$method = Flight::request()->getMethod();注意: getMethod() 方法首先从 $_SERVER['REQUEST_METHOD'] 拉取方法,然后如果存在 $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'] 或 $_REQUEST['_method'],它可以被覆盖。
请求对象属性
请求对象提供以下属性:
- body - 原始 HTTP 请求主体
- url - 被请求的 URL
- base - URL 的父子目录
- method - 请求方法 (GET, POST, PUT, DELETE)
- referrer - 引用 URL
- ip - 客户端 IP 地址
- ajax - 请求是否为 AJAX 请求
- scheme - 服务器协议 (http, https)
- user_agent - 浏览器信息
- type - 内容类型
- length - 内容长度
- query - 查询字符串参数
- data - 帖子数据或 JSON 数据
- cookies - Cookie 数据
- files - 上传的文件
- secure - 连接是否安全
- accept - HTTP 接受参数
- proxy_ip - 客户端的代理 IP 地址。按顺序扫描
$_SERVER数组中的HTTP_CLIENT_IP、HTTP_X_FORWARDED_FOR、HTTP_X_FORWARDED、HTTP_X_CLUSTER_CLIENT_IP、HTTP_FORWARDED_FOR、HTTP_FORWARDED。 - host - 请求主机名
- servername - 来自
$_SERVER的 SERVER_NAME
辅助方法
有一些辅助方法可以拼凑 URL 的部分,或处理某些头部。
完整 URL
你可以使用 getFullUrl() 方法访问完整的请求 URL:
$url = Flight::request()->getFullUrl();
// https://example.com/some/path?foo=bar基础 URL
你可以使用 getBaseUrl() 方法访问基础 URL:
// http://example.com/path/to/something/cool?query=yes+thanks
$url = Flight::request()->getBaseUrl();
// https://example.com
// 注意,没有尾随斜杠。查询解析
你可以将 URL 传递给 parseQuery() 方法来解析查询字符串为关联数组:
$query = Flight::request()->parseQuery('https://example.com/some/path?foo=bar');
// ['foo' => 'bar']协商内容接受类型
v3.17.2
你可以使用 negotiateContentType() 方法根据客户端发送的 Accept 头部确定最佳响应内容类型。
// 示例 Accept 头部:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
// 下面定义你支持的内容。
$availableTypes = ['application/json', 'application/xml'];
$typeToServe = Flight::request()->negotiateContentType($availableTypes);
if ($typeToServe === 'application/json') {
// 服务 JSON 响应
} elseif ($typeToServe === 'application/xml') {
// 服务 XML 响应
} else {
// 默认使用其他内容或抛出错误
}注意: 如果在
Accept头部中找不到任何可用类型,该方法将返回null。如果没有定义Accept头部,该方法将返回$availableTypes数组中的第一个类型。
另请参阅
- Routing - 查看如何将路由映射到控制器并渲染视图。
- Responses - 如何自定义 HTTP 响应。
- Why a Framework? - 请求如何融入大局。
- Collections - 处理数据集合。
- Uploaded File Handler - 处理文件上传。
故障排除
- 如果你的 Web 服务器位于代理、负载均衡器等后面,
request()->ip和request()->proxy_ip可能不同。
更新日志
- v3.17.2 - 添加了 negotiateContentType()
- v3.12.0 - 添加了通过请求对象处理文件上传的能力。
- v1.0 - 初始发布。