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 標頭

您可以透過 yii\web\Request::$headers 屬性傳回的 標頭集合 取得 HTTP 標頭資訊。例如,

// $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 支援透過 request 組件的 trustedHostssecureHeadersipHeaderssecureProtocolHeadersportHeaders(自 2.0.46 起)屬性來配置信任的代理伺服器。

以下是在 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']
    ],
],

使用上述配置,secureHeaders 中列出的所有標頭都會從請求中篩選掉,除非請求是由代理伺服器發出的,否則 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 上編輯 !