IncomingRequest 类
IncomingRequest 类提供了客户端(如浏览器)HTTP 请求的面向对象表示。 除了下文列出的方法外,此类还继承并可访问 Request 和 Message 类的所有方法。
访问请求
如果当前类继承自 CodeIgniter\Controller,则 Request 类的实例已自动填充,并可通过类属性访问:
<?php
namespace App\Controllers;
use CodeIgniter\Controller;
class UserController extends Controller
{
public function index()
{
if ($this->request->isAJAX()) {
// ...
}
}
}
如果不在控制器内,但仍需访问应用程序的 Request 对象,可通过 Services 类 获取副本:
<?php
$request = service('request');
不过,如果类不是控制器,建议将 Request 作为依赖项传入并存为类属性:
<?php
namespace App\Libraries;
use CodeIgniter\HTTP\RequestInterface;
class SomeClass
{
protected $request;
public function __construct(RequestInterface $request)
{
$this->request = $request;
}
}
$someClass = new SomeClass(service('request'));
判断请求类型
请求可能有多种类型,包括 AJAX 请求或命令行请求。可使用 isAJAX() 和 isCLI() 方法进行检查:
<?php
// Check for AJAX request.
if ($request->isAJAX()) {
// ...
}
// Check for CLI Request
if ($request->isCLI()) {
// ...
}
备注
isAJAX() 方法依赖于 X-Requested-With 标头。在某些情况下,通过 JavaScript(如 fetch)发起的 XHR 请求默认不会发送该标头。请参阅 AJAX 请求 章节了解如何解决此问题。
is()
Added in version 4.3.0.
自 v4.3.0 起,可使用 is() 方法。该方法接受 HTTP 方法、'ajax' 或 'json',并返回布尔值。
备注
虽然 HTTP 方法区分大小写,但此参数不区分大小写。
<?php
// Checks HTTP methods. Returns boolean.
$request->is('get');
$request->is('post');
$request->is('put');
$request->is('delete');
$request->is('head');
$request->is('patch');
$request->is('options');
// Checks if it is an AJAX request. The same as `$request->isAJAX()`.
$request->is('ajax');
// Checks if it is a JSON request.
$request->is('json');
getMethod()
可使用 getMethod() 方法检查此请求代表的 HTTP 方法:
<?php
// Returns 'POST'
$method = $request->getMethod();
HTTP 方法区分大小写。按照惯例,标准方法均由大写 US-ASCII 字母定义。
备注
v4.5.0 之前,该方法默认返回小写字符串(如 'get'、'post' 等),但这其实是一个 Bug。
可通过 strtolower() 封装调用以获取小写版本:
// 返回 'get'
$method = strtolower($request->getMethod());
还可使用 isSecure() 方法检查是否通过 HTTPS 连接发起请求:
<?php
if (! $request->isSecure()) {
force_https();
}
获取输入数据
可通过 Request 对象从 $_GET、$_POST、$_COOKIE、$_SERVER 和 $_ENV 中获取输入。
数据不会被自动过滤,将返回请求传入的原始输入数据。
备注
使用全局变量并非良好实践。原则上应避免使用,建议使用 Request 对象的方法。
使用这些方法而非直接访问(如 $_POST['something'])的主要优势在于:如果项不存在将返回 null,且支持数据过滤。这使得在使用数据前无需先测试其是否存在。换言之,通常可能需要这样做:
<?php
$something = $_POST['foo'] ?? null;
使用 CodeIgniter 的内置方法,只需:
<?php
$something = $request->getPost('foo');
获取数据
getGet()
getGet() 方法将从 $_GET 中获取数据。
$request->getGet()
getPost()
getPost() 方法将从 $_POST 中获取数据。
$request->getPost()
getServer()
getServer() 方法将从 $_SERVER 中获取数据。
$request->getServer()
getPostGet()
此外,还有一些实用方法可从 $_GET 或 $_POST 中检索信息,并支持控制搜索顺序:
$request->getPostGet()- 先检查$_POST,再检查$_GET
getGetPost()
$request->getGetPost()- 先检查$_GET,再检查$_POST
getVar()
重要
此方法仅为了向后兼容而存在。请勿在新项目中使用。即使已经在用,也建议换用其他更合适的方法。
getVar() 方法将从 $_REQUEST 中获取数据,因此会返回来自 $_GET、$_POST 或 $_COOKIE 的任何数据(取决于 php.ini 中的 request-order)。
警告
如果只想验证 POST 数据,请勿使用 getVar()。较新的值会覆盖旧值。如果在 request-order 中将 "C" 设置在 "P" 之后,同名的 Cookie 值可能会覆盖 POST 值。
备注
如果传入请求的 Content-Type 标头设为 application/json,getVar() 方法将返回 JSON 数据而非 $_REQUEST 数据。
获取 JSON 数据
可使用 getJSON() 将 php://input 的内容作为 JSON 流获取。
备注
此方法无法检查传入数据是否为有效的 JSON,仅应在确定预期为 JSON 时使用。
<?php
$json = $request->getJSON();
默认情况下,该方法将 JSON 数据中的所有对象作为对象返回。如果希望将其转换为关联数组,请将第一个参数设为 true。
第二和第三个参数分别对应 PHP 函数 json_decode() 的 $depth 和 $flags 参数。
从 JSON 获取特定数据
通过向 getJsonVar() 传入变量名,可获取 JSON 流中的特定数据;也可使用“点”语法深入 JSON 获取非根级别的数据。
<?php
/*
* With a request body of:
* {
* "foo": "bar",
* "fizz": {
* "buzz": "baz"
* }
* }
*/
$data = $request->getJsonVar('foo');
// $data = "bar"
$data = $request->getJsonVar('fizz.buzz');
// $data = "baz"
如果希望结果是关联数组而非对象,可在第二个参数传入 true:
<?php
// With the same request as above
$data = $request->getJsonVar('fizz');
// $data->buzz = "baz"
$data = $request->getJsonVar('fizz', true);
// $data = ["buzz" => "baz"]
备注
有关“点”语法的更多信息,请参阅 数组 辅助函数中 dot_array_search() 的文档。
获取原始数据(PUT、PATCH、DELETE)
最后,可使用 getRawInput() 将 php://input 的内容作为原始流获取:
<?php
$data = $request->getRawInput();
这将检索数据并将其转换为数组。如下所示:
<?php
var_dump($request->getRawInput());
/*
* Outputs:
* [
* 'Param1' => 'Value1',
* 'Param2' => 'Value2',
* ]
*/
也可使用 getRawInputVar() 从原始流中获取特定变量并进行过滤。
<?php
// When the request body is 'foo=one&bar=two&baz[]=10&baz[]=20'
var_dump($request->getRawInputVar('bar'));
// Outputs: two
// foo=one&bar=two&baz[]=10&baz[]=20
var_dump($request->getRawInputVar(['foo', 'bar']));
/*
* Outputs:
* [
* 'foo' => 'one',
* 'bar' => 'two'
* ]
*/
// foo=one&bar=two&baz[]=10&baz[]=20
var_dump($request->getRawInputVar('baz'));
/*
* Outputs:
* [
* '10',
* '20'
* ]
*/
// foo=one&bar=two&baz[]=10&baz[]=20
var_dump($request->getRawInputVar('baz.0'));
// Outputs: 10
过滤输入数据
为了维护应用程序安全,应在访问所有输入时进行过滤。可将过滤器类型作为这些方法的第二个参数传入。过滤功能使用原生的 filter_var() 函数。关于有效过滤器类型的列表,请参考 PHP 手册中的 可用过滤器列表。
过滤 POST 变量示例如下:
<?php
$email = $request->getPost('email', FILTER_SANITIZE_EMAIL);
除 getJSON() 和 getRawInput() 外,上述所有方法均支持在第二个参数中传入过滤器类型。
获取标头
可使用 headers() 方法访问随请求发送的所有标头。该方法返回一个数组,键为标头名称,值为 CodeIgniter\HTTP\Header 实例:
<?php
var_dump($request->headers());
/*
* Outputs:
* [
* 'Host' => CodeIgniter\HTTP\Header,
* 'Cache-Control' => CodeIgniter\HTTP\Header,
* 'Accept' => CodeIgniter\HTTP\Header,
* ]
*/
如果只需要单个标头,可将名称传入 header() 方法。如果该标头存在,将以不区分大小写的方式获取指定的标头对象;否则返回 null:
<?php
// these are all equivalent
$host = $request->header('host');
$host = $request->header('Host');
$host = $request->header('HOST');
可随时使用 hasHeader() 检查此请求中是否存在某个标头:
<?php
if ($request->hasHeader('DNT')) {
// Don't track something...
}
如果需要以字符串形式获取一行内的所有标头值,可使用 getHeaderLine() 方法:
<?php
// Accept-Encoding: gzip, deflate, sdch
echo 'Accept-Encoding: ' . $request->getHeaderLine('accept-encoding');
如果需要包含名称和值的完整标头字符串,直接将标头转换为字符串即可:
<?php
echo (string) $header;
请求 URL
可通过 $request->getUri() 方法获取代表当前请求 URI 的 URI 对象。将此对象转换为字符串可获取当前请求的完整 URL:
<?php
$uri = (string) $request->getUri();
该对象提供了获取请求中任何部分的完整能力:
<?php
$uri = $request->getUri();
echo $uri->getScheme(); // http
echo $uri->getAuthority(); // snoopy:password@example.com:88
echo $uri->getUserInfo(); // snoopy:password
echo $uri->getHost(); // example.com
echo $uri->getPort(); // 88
echo $uri->getPath(); // /path/to/page
echo $uri->getRoutePath(); // path/to/page
echo $uri->getQuery(); // foo=bar&bar=baz
print_r($uri->getSegments()); // Array ( [0] => path [1] => to [2] => page )
echo $uri->getSegment(1); // path
echo $uri->getTotalSegments(); // 3
可使用 getRoutePath() 处理当前 URI 字符串(相对于 baseURL 的路径)。
备注
getRoutePath() 方法自 v4.4.0 起可用。在 v4.4.0 之前,getPath() 方法返回相对于 baseURL 的路径。
上传文件
可通过 $request->getFiles() 获取所有上传文件的信息,该方法返回 CodeIgniter\HTTP\Files\UploadedFile 实例数组。这有助于简化上传文件的处理,并采用最佳实践以降低安全风险。
<?php
$files = $request->getFiles();
详情请参阅 处理上传文件。
可根据 HTML 文件输入框中给定的文件名,单独获取某个上传文件:
<?php
$file = $request->getFile('userfile');
如果是多文件上传,可根据 HTML 文件输入框中给定的文件名,获取同名上传文件的数组:
<?php
$files = $request->getFileMultiple('userfile');
备注
此处获取的文件对象本质上对应于 $_FILES。即使用户仅点击表单提交按钮而未上传任何文件,该文件依然存在。可通过 UploadedFile 中的 isValid() 方法检查文件是否确实已上传。详情请参阅 验证文件。
内容协商
可通过 negotiate() 方法轻松与请求进行内容类型协商:
<?php
$language = $request->negotiate('language', ['en-US', 'en-GB', 'fr', 'es-mx']);
$imageType = $request->negotiate('media', ['image/png', 'image/jpg']);
$charset = $request->negotiate('charset', ['UTF-8', 'UTF-16']);
$contentType = $request->negotiate('media', ['text/html', 'text/xml']);
$encoding = $request->negotiate('encoding', ['gzip', 'compress']);
有关更多详情,请参阅 内容协商 页面。
类参考
继承自父类的可用方法包括:
CodeIgniter\HTTP\Request::getIPAddress()CodeIgniter\HTTP\Request::isValidIP()CodeIgniter\HTTP\Request::getMethod()CodeIgniter\HTTP\Request::setMethod()CodeIgniter\HTTP\Request::getServer()CodeIgniter\HTTP\Request::setGlobal()CodeIgniter\HTTP\Request::fetchGlobal()CodeIgniter\HTTP\Message::getBody()CodeIgniter\HTTP\Message::setBody()CodeIgniter\HTTP\Message::appendBody()CodeIgniter\HTTP\Message::populateHeaders()CodeIgniter\HTTP\Message::headers()CodeIgniter\HTTP\Message::header()CodeIgniter\HTTP\Message::hasHeader()CodeIgniter\HTTP\Message::getHeaderLine()CodeIgniter\HTTP\Message::setHeader()CodeIgniter\HTTP\Message::removeHeader()CodeIgniter\HTTP\Message::appendHeader()CodeIgniter\HTTP\Message::prependHeader()CodeIgniter\HTTP\Message::getProtocolVersion()CodeIgniter\HTTP\Message::setProtocolVersion()
- class CodeIgniter\HTTP\IncomingRequest
- isCLI()
- 返回:
如果请求是从命令行发起的,返回 true,否则返回 false。
- 返回类型:
bool
- isAJAX()
- 返回:
如果请求是 AJAX 请求,返回 true,否则返回 false。
- 返回类型:
bool
- isSecure()
- 返回:
如果请求是 HTTPS 请求,返回 true,否则返回 false。
- 返回类型:
bool
- getVar([$index = null[, $filter = null[, $flags = null]]])
- 参数:
- 返回:
如果未提供参数则返回
$_REQUEST;如果找到则返回 REQUEST 值,未找到则返回 null。- 返回类型:
array|bool|float|int|object|string|null
重要
此方法仅为了向后兼容而存在。请勿在新项目中使用。即使已经在用,也建议换用其他更合适的方法。
此方法与
getGet()完全相同,只是它获取的是 REQUEST 数据。
- getGet([$index = null[, $filter = null[, $flags = null]]])
- 参数:
- 返回:
如果未提供参数则返回
$_GET;如果找到则返回 GET 值,未找到则返回 null。- 返回类型:
array|bool|float|int|object|string|null
第一个参数包含要查找的 GET 项名称:
<?php $request->getGet('some_data');
如果要获取的项目不存在,该方法将返回 null。
第二个可选参数支持通过 PHP 过滤器运行数据。将所需的过滤器类型作为第二个参数传入:
<?php $request->getGet('some_data', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
若要返回所有 GET 项的数组,请在调用时不带任何参数。
若要返回所有 GET 项并对其进行过滤,请将第一个参数设为 null,同时将第二个参数设为要使用的过滤器:
<?php $request->getGet(null, FILTER_SANITIZE_FULL_SPECIAL_CHARS); // returns all GET items with string sanitation
若要返回多个 GET 参数的数组,请将所有需要的键作为数组传入:
<?php $request->getGet(['field1', 'field2']);
此处规则相同,若要在检索参数时进行过滤,请将第二个参数设为要应用的过滤器类型:
<?php $request->getGet(['field1', 'field2'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
- getPost([$index = null[, $filter = null[, $flags = null]]])
- 参数:
- 返回:
如果未提供参数则返回
$_POST;如果找到则返回 POST 值,未找到则返回 null。- 返回类型:
array|bool|float|int|object|string|null
此方法与
getGet()完全相同,只是它获取的是 POST 数据。
- getPostGet([$index = null[, $filter = null[, $flags = null]]])
- 参数:
- 返回:
如果未指定参数,则返回合并后的
$_POST和$_GET(名称冲突时优先使用 POST 值);否则先查找 POST 值,未找到则查找 GET 值,若均未找到则返回 null。- 返回类型:
array|bool|float|int|object|string|null
此方法的工作方式与
getPost()和getGet()基本相同,只是将二者结合。它会同时在 POST 和 GET 流中搜索数据,先查找 POST,然后查找 GET:<?php $request->getPostGet('field1');
如果未指定索引,将返回合并后的 POST 和 GET 流。若发生名称冲突,将优先使用 POST 数据。
- getGetPost([$index = null[, $filter = null[, $flags = null]]])
- 参数:
- 返回:
如果未指定参数,则返回合并后的
$_GET和$_POST(名称冲突时优先使用 GET 值);否则先查找 GET 值,未找到则查找 POST 值,若均未找到则返回 null。- 返回类型:
array|bool|float|int|object|string|null
此方法的工作方式与
getPost()和getGet()基本相同,只是将二者结合。它会同时在 GET 和 POST 流中搜索数据,先查找 GET,然后查找 POST:<?php $request->getGetPost('field1');
如果未指定索引,将返回合并后的 GET 和 POST 流。若发生名称冲突,将优先使用 GET 数据。
- getCookie([$index = null[, $filter = null[, $flags = null]]])
- 参数:
- 返回:
如果未提供参数则返回
$_COOKIE;如果找到则返回 COOKIE 值,未找到则返回 null。- 返回类型:
array|bool|float|int|object|string|null
此方法与
getPost()和getGet()完全相同,只是它获取的是 Cookie 数据:<?php $request->getCookie('some_cookie'); $request->getCookie('some_cookie', FILTER_SANITIZE_FULL_SPECIAL_CHARS); // with filter
若要返回多个 Cookie 值的数组,请将所有需要的键作为数组传入:
<?php $request->getCookie(['some_cookie', 'some_cookie2']);
备注
与 Cookie 辅助函数 中的
get_cookie()函数不同,此方法不会自动附加配置的Config\Cookie::$prefix值。
- getServer([$index = null[, $filter = null[, $flags = null]]])
- 参数:
- 返回:
如果找到则返回
$_SERVER项的值,未找到则返回 null。- 返回类型:
array|bool|float|int|object|string|null
此方法与
getPost()、getGet()和getCookie()方法完全相同,只是它获取的是 Server 数据($_SERVER):<?php $request->getServer('some_data');
若要返回多个
$_SERVER值的数组,请将所有需要的键作为数组传入。<?php $request->getServer(['SERVER_PROTOCOL', 'REQUEST_URI']);
- getUserAgent()
- 返回:
SERVER 数据中的 User Agent 字符串;如果未找到则返回 null。
- 返回类型:
此方法从 SERVER 数据中返回 User Agent 实例:
<?php $request->getUserAgent();
- getPath()
- 返回:
当前相对于 baseURL 的 URI 路径
- 返回类型:
string
此方法返回当前相对于 baseURL 的 URI 路径。
备注
v4.4.0 之前,这是确定“当前 URI”最安全的方法,因为
IncomingRequest::$uri可能无法识别应用程序中完整的基准 URL 配置。