2 个关注者

请求

对应用程序发出的请求用 yii\web\Request 对象表示,这些对象提供诸如请求参数、HTTP 头部、Cookie 等信息。对于给定的请求,您可以通过 request 应用程序组件 访问相应的请求对象,该组件默认情况下是 yii\web\Request 的实例。在本节中,我们将介绍如何在应用程序中使用此组件。

请求参数

要获取请求参数,可以调用 request 组件的 get()post() 方法。它们分别返回 $_GET$_POST 的值。例如,

$request = Yii::$app->request;

$get = $request->get();
// equivalent to: $get = $_GET;

$id = $request->get('id');
// equivalent to: $id = isset($_GET['id']) ? $_GET['id'] : null;

$id = $request->get('id', 1);
// equivalent to: $id = isset($_GET['id']) ? $_GET['id'] : 1;

$post = $request->post();
// equivalent to: $post = $_POST;

$name = $request->post('name');
// equivalent to: $name = isset($_POST['name']) ? $_POST['name'] : null;

$name = $request->post('name', '');
// equivalent to: $name = isset($_POST['name']) ? $_POST['name'] : '';

信息:建议您使用上面所示的 request 组件来获取请求参数,而不是直接访问 $_GET$_POST。这将使编写测试更容易,因为您可以使用伪造的请求数据创建一个模拟请求组件。

在实现 RESTful API 时,您通常需要检索通过 PUT、PATCH 或其他 请求方法 提交的参数。您可以通过调用 yii\web\Request::getBodyParam() 方法来获取这些参数。例如,

$request = Yii::$app->request;

// returns all parameters
$params = $request->bodyParams;

// returns the parameter "id"
$param = $request->getBodyParam('id');

信息:GET 参数不同,通过 POSTPUTPATCH 等提交的参数在请求主体中发送。request 组件将在您通过上面描述的方法访问这些参数时解析这些参数。您可以通过配置 yii\web\Request::$parsers 属性来自定义这些参数的解析方式。

请求方法

您可以通过表达式 Yii::$app->request->method 获取当前请求使用的 HTTP 方法。还提供了一组布尔属性,供您检查当前方法是否为特定类型。例如,

$request = Yii::$app->request;

if ($request->isAjax) { /* the request is an AJAX request */ }
if ($request->isGet)  { /* the request method is GET */ }
if ($request->isPost) { /* the request method is POST */ }
if ($request->isPut)  { /* the request method is PUT */ }

请求 URL

request 组件提供了许多检查当前请求 URL 的方法。

假设正在请求的 URL 为 https://example.com/admin/index.php/product?id=100,您可以获取此 URL 的各个部分,如下所示

  • url:返回 /admin/index.php/product?id=100,即不含主机信息部分的 URL。
  • absoluteUrl:返回 https://example.com/admin/index.php/product?id=100,即包含主机信息部分的整个 URL。
  • hostInfo:返回 https://example.com,即 URL 的主机信息部分。
  • pathInfo:返回 /product,即入口脚本之后和问号(查询字符串)之前的部分。
  • queryString:返回 id=100,即问号之后的部分。
  • baseUrl: 返回 /admin,这是主机信息之后和入口脚本名称之前的部分。
  • scriptUrl: 返回 /admin/index.php,这是不包含路径信息和查询字符串的 URL。
  • serverName: 返回 example.com,这是 URL 中的主机名。
  • serverPort: 返回 80,这是 Web 服务器使用的端口。

HTTP 头部

您可以通过 header collection 获取 HTTP 头部信息,该信息由 yii\web\Request::$headers 属性返回。例如,

// $headers is an object of yii\web\HeaderCollection 
$headers = Yii::$app->request->headers;

// returns the Accept header value
$accept = $headers->get('Accept');

if ($headers->has('User-Agent')) { /* there is User-Agent header */ }

request 组件还支持快速访问一些常用的头部,包括

  • userAgent: 返回 User-Agent 头部的值。
  • contentType: 返回 Content-Type 头部的值,它指示请求体中数据的 MIME 类型。
  • acceptableContentTypes: 返回用户可接受的内容 MIME 类型。返回的类型按其质量得分排序。得分最高的类型将首先返回。
  • acceptableLanguages: 返回用户可接受的语言。返回的语言按其偏好级别排序。第一个元素代表最喜欢的语言。

如果您的应用程序支持多种语言,并且您想以最终用户最喜欢的语言显示页面,您可以使用语言协商方法 yii\web\Request::getPreferredLanguage()。此方法接收应用程序支持的语言列表,将它们与 acceptableLanguages 进行比较,并返回最合适的语言。

提示:您也可以使用 ContentNegotiator 过滤器来动态确定响应中应使用什么内容类型和语言。该过滤器在上述属性和方法之上实现了内容协商。

客户端信息

您可以分别通过 userHostuserIP 获取客户端机器的主机名和 IP 地址。例如,

$userHost = Yii::$app->request->userHost;
$userIP = Yii::$app->request->userIP;

受信任的代理和头部

在上一节中,您已经了解了如何获取用户的信息,例如主机和 IP 地址。这在正常情况下可以直接使用,即使用单个 Web 服务器提供网站。但是,如果您的 Yii 应用程序在反向代理之后运行,则需要添加额外的配置来检索此信息,因为直接客户端现在是代理,并且用户 IP 地址通过代理设置的头部传递给 Yii 应用程序。

除非您明确信任代理,否则您不应该盲目信任代理提供的头部。从 2.0.13 开始,Yii 支持通过 trustedHostssecureHeadersipHeaderssecureProtocolHeadersportHeaders(从 2.0.46 开始)属性配置受信任的代理,这些属性属于 request 组件。

以下是一个在反向代理数组之后运行的应用程序的请求配置,这些反向代理位于 10.0.2.0/24 IP 网络中

'request' => [
    // ...
    'trustedHosts' => [
        '10.0.2.0/24',
    ],
],

IP 默认情况下由代理在 X-Forwarded-For 头部中发送,协议(httphttps)在 X-Forwarded-Proto 中发送。

如果您的代理使用不同的头部,您可以使用请求配置来调整它们,例如

'request' => [
    // ...
    'trustedHosts' => [
        '10.0.2.0/24' => [
            'X-ProxyUser-Ip',
            'Front-End-Https',
        ],
    ],
    'secureHeaders' => [
        'X-Forwarded-For',
        'X-Forwarded-Host',
        'X-Forwarded-Proto',
        'X-Forwarded-Port',
        'X-Proxy-User-Ip',
        'Front-End-Https',
    ],
    'ipHeaders' => [
        'X-Proxy-User-Ip',
    ],
    'secureProtocolHeaders' => [
        'Front-End-Https' => ['on']
    ],
],

通过上述配置,所有列出的头部都将从请求中过滤掉,除非请求是由代理发出的,在这种情况下,除了 X-ProxyUser-IpFront-End-Https 头部。在这种情况下,前者用于检索用户 IP,如 ipHeaders 中配置的,而后者将用于确定 yii\web\Request::getIsSecureConnection() 的结果。

从 2.0.31 开始,支持 RFC 7239 Forwarded 头部。为了启用它,您需要将头部名称添加到 secureHeaders。确保您的代理正在设置它,否则最终用户将能够伪造 IP 和协议。

已解析的用户 IP

如果用户的 IP 地址在 Yii 应用程序之前解析(例如 ngx_http_realip_module 或类似的),request 组件将使用以下配置正常工作

'request' => [
    // ...
    'trustedHosts' => [
        '0.0.0.0/0',
    ],
    'ipHeaders' => [], 
],

在这种情况下,userIP 的值将等于 $_SERVER['REMOTE_ADDR']。此外,从 HTTP 头部解析的属性也将正常工作(例如 yii\web\Request::getIsSecureConnection())。

警告:trustedHosts=['0.0.0.0/0'] 设置假定所有 IP 都可信。

发现错别字,或您认为此页面需要改进?
在 github 上编辑 !