首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

Yii 2.0 請求與響應處理全解析:Request/Response 組件深度應用

     編輯:PHP 相關知識

一、Request 組件:處理 HTTP 請求

Yii 以 yii\web\Request 物件封裝 HTTP 請求,透過 \Yii::$app->request 存取。它提供參數獲取、HTTP 標頭、URL 解析、客戶端資訊等功能。

1. 請求參數獲取

$request = \Yii::$app->request;
// GET 參數
$get = $request->get();           // 所有 GET 參數
$id = $request->get('id');        // 單一參數 (不存在回傳 null)
$id = $request->get('id', 1);     // 帶預設值
// POST 參數
$post = $request->post();
$name = $request->post('name', '');
// RESTful 請求體參數 (PUT/PATCH 等)
$params = $request->bodyParams;
$param = $request->getBodyParam('id');

最佳實踐:統一使用 Request 組件而非直接存取 $_GET/$_POST,便於測試與模擬請求。

2. 請求方法判斷

$request = \Yii::$app->request;
$method = $request->method; // 'GET', 'POST', 'PUT' 等
// 布林屬性快速判斷
if ($request->isAjax) { /* AJAX 請求 */ }
if ($request->isGet)  { /* GET 請求 */ }
if ($request->isPost) { /* POST 請求 */ }
if ($request->isPut)  { /* PUT 請求 */ }

3. URL 解析

假設請求 URL:https://example.com/admin/index.php/product?id=100

  • url:/admin/index.php/product?id=100 (不含 host)
  • absoluteUrl:完整 URL
  • hostInfo:https://example.com
  • pathInfo:/product (入口腳本後、查詢字串前)
  • queryString:id=100
  • baseUrl:/admin (host 後、入口腳本前)
  • scriptUrl:/admin/index.php
  • serverName:example.com
  • serverPort:80

4. HTTP 標頭存取

$headers = $request->headers; // HeaderCollection 物件
$accept = $headers->get('Accept');
if ($headers->has('User-Agent')) { /* ... */ }

// 常用標頭快捷屬性
$userAgent = $request->userAgent;
$contentType = $request->contentType;
$acceptableTypes = $request->acceptableContentTypes; // 依品質排序
$acceptableLangs = $request->acceptableLanguages;    // 依偏好排序

5. 語言協商

// 根據 Accept-Language 與應用支援語言自動協商
$language = $request->getPreferredLanguage(['en-US', 'zh-TW', 'zh-CN']);
// 或使用 ContentNegotiator 過濾器自動處理響應格式與語言

6. 客戶端資訊

$userHost = $request->userHost; // 主機名
$userIP = $request->userIP;     // IP 位址

二、Response 組件:構建 HTTP 響應

yii\web\Response 封裝 HTTP 響應,包含狀態碼、標頭、主體內容。主要透過 \Yii::$app->response 操作。

1. 狀態碼設定

// 成功預設 200,通常無需明確設定
\Yii::$app->response->statusCode = 200;
// 失敗拋出對應 HTTP 例外
throw new \yii\web\NotFoundHttpException(); // 404
throw new \yii\web\ForbiddenHttpException(); // 403
// 自定義狀態碼
throw new \yii\web\HttpException(402);

Yii 預定義常見 HTTP 例外:BadRequestHttpException(400)、UnauthorizedHttpException(401)、ServerErrorHttpException(500) 等。

2. HTTP 標頭操作

$headers = \Yii::$app->response->headers;
$headers->add('Pragma', 'no-cache');    // 新增 (不覆蓋)
$headers->set('Pragma', 'no-cache');    // 設定 (覆蓋)
$values = $headers->remove('Pragma');   // 移除並回傳舊值

注意:標頭名稱大小寫敏感;send() 呼叫前新增的標頭才會發送。

3. 響應主體與格式化

$response = \Yii::$app->response;
// 直接設定內容 (已格式化字串)
$response->content = 'hello world!';
// 設定格式與資料 (自動格式化)
$response->format = \yii\web\Response::FORMAT_JSON;
$response->data = ['message' => 'hello world', 'code' => 100];

支援格式:FORMAT_HTML (預設)、FORMAT_JSON、FORMAT_XML、FORMAT_JSONP。可自訂 Formatter。

4. 控制器動作隱式返回

// 預設 HTML 格式
public function actionIndex() {
    return $this->render('index'); // 視圖渲染結果
}
// JSON API
public function actionInfo() {
    \Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
    return ['message' => 'hello world', 'code' => 100];
}
// 回傳自建 Response 物件
public function actionInfo() {
    return \Yii::createObject([
        'class' => 'yii\web\Response',
        'format' => \yii\web\Response::FORMAT_JSON,
        'data' => ['message' => 'hello world'],
    ]);

5. 瀏覽器重導向

// 控制器縮寫
public function actionOld() {
    return $this->redirect('https://example.com/new', 301); // 301 永久重導
}
// 非控制器環境
\Yii::$app->response->redirect('https://example.com/new', 301)->send();

AJAX 重導向:自動設定 X-Redirect 標頭,搭配 yii.js 實現前端跳轉。

6. 檔案下載

// 控制器中
public function actionDownload() {
    return \Yii::$app->response->sendFile('path/to/file.txt');
}
// 其他位置
\Yii::$app->response->sendFile('path/to/file.txt')->send();

大檔案建議用 sendStreamAsFile() 節省記憶體。支援 X-Sendfile/X-Accel-Redirect 讓 Web Server 直接傳檔。

7. 響應發送流程與事件

// 發送步驟 (send() 內部流程)
1. 觸發 EVENT_BEFORE_SEND
2. prepare() 格式化 data -> content
3. 觸發 EVENT_AFTER_PREPARE
4. sendHeaders() 發送標頭
5. sendContent() 發送主體
6. 觸發 EVENT_AFTER_SEND

send() 於 Application::run() 結尾自動呼叫,重複呼叫會被忽略。可利用事件修改響應 (如壓縮、快取標頭)。

總結

Yii 的 Request/Response 組件完整封裝 HTTP 協定細節,提供直觀的物件導向介面。善用參數綁定、格式化輸出、事件機制,能構建安全、規範、易測試的 Web 應用。進階場景可結合 ContentNegotiator、自訂 Formatter、X-Sendfile 等功能提升開發效率與效能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved