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

Symfony2 控制器深度解析:從基礎用法到進階模式

     編輯:PHP 綜合知識

控制器核心職責

在 Symfony2 架構中,控制器是處理 HTTP 請求並返回 HTTP 回應的核心元件。它接收 Request 物件,執行業務邏輯(資料庫查詢、表單處理、郵件發送等),最終必須返回一個 Response 物件。無論回應內容是 HTML、JSON、XML、圖片、重定向或 404 錯誤,本質上都是 Response 物件的不同表現形式。

請求-控制器-回應生命週期

  1. 所有請求經由統一前端控制器(app.php 或 app_dev.php)進入應用程式
  2. 路由器從 Request 解析 URI,匹配對應路由並讀取 _controller 參數
  3. 匹配成功的控制器被執行,建立並返回 Response 物件
  4. HTTP 標頭與回應內容發送回客戶端

注意:前端控制器與控制器是不同概念。前端控制器是 web/ 目錄下的 PHP 入口檔案,每個應用通常只有一個生產版(app.php)和一個開發版(app_dev.php)。

最簡控制器範例

use Symfony\Component\HttpFoundation\Response;

public function helloAction()
{
    return new Response('Hello world!');
}

控制器類結構慣例

// src/Acme/HelloBundle/Controller/HelloController.php
namespace Acme\HelloBundle\Controller;

use Symfony\Component\HttpFoundation\Response;

class HelloController
{
    public function indexAction($name)
    {
        return new Response('Hello '.$name.'!');
    }
}

命名慣例:

  • 類名以 Controller 結尾(路由配置時只取前綴)
  • 動作方法以 Action 結尾(路由配置時只取前綴)
  • 邏輯控制器名稱格式:Bundle:Controller:action → AcmeHelloBundle:Hello:index

路由參數自動綁定

路由中的佔位符與 defaults 會自動映射到控制器方法參數(按名稱而非順序):

# 路由配置
hello:
    pattern: /hello/{first_name}/{last_name}
    defaults: { _controller: AcmeHelloBundle:Hello:index, color: green }
public function indexAction($first_name, $last_name, $color)
{
    // 參數自動注入,順序可任意調換
}

規則:

  • 控制器參數必須在路由中有對應定義(除非設為可選)
  • 路由中定義的參數不一定要在控制器中使用
  • 特殊參數 _route 可獲取當前路由名稱

Request 物件注入

在方法簽名中型別提示 Request 即可自動注入:

use Symfony\Component\HttpFoundation\Request;

public function updateAction(Request $request)
{
    $form = $this->createForm(...);
    $form->bindRequest($request);
    // ...
}

基礎控制器類優勢

繼承 Symfony\Bundle\FrameworkBundle\Controller\Controller 可獲得豐富輔助方法:

重定向

public function indexAction()
{
    return $this->redirect($this->generateUrl('homepage'));  // 302
    // return $this->redirect($this->generateUrl('homepage'), 301); // 301
}

內部轉發

public function indexAction($name)
{
    $response = $this->forward('AcmeHelloBundle:Hello:fancy', array(
        'name' => $name,
        'color' => 'green'
    ));
    return $response;
}

轉發是內部子請求,不會觸發瀏覽器重定向。目標控制器:

public function fancyAction($name, $color)
{
    // 建立並返回 Response 物件
}

模板渲染

// 簡化寫法
return $this->render('AcmeHelloBundle:Hello:index.html.twig', array('name' => $name));

// 等同於
$content = $this->renderView('AcmeHelloBundle:Hello:index.html.twig', array('name' => $name));
return new Response($content);

服務存取

$request = $this->getRequest();
$templating = $this->get('templating');
$router = $this->get('router');
$mailer = $this->get('mailer');

查看所有可用服務:php app/console container:debug

錯誤處理與 404 頁面

public function indexAction()
{
    $product = // 從資料庫查詢
    if (!$product) {
        throw $this->createNotFoundException('產品不存在');
    }
    return $this->render(...);
}

拋出任意 Exception 會自動轉為 500 錯誤回應。

Session 管理

$session = $this->getRequest()->getSession();

// 儲存屬性
$session->set('foo', 'bar');

// 讀取屬性
$foo = $session->get('foo');

// 設定語系
$session->setLocale('fr');

閃存訊息

適用於重定向後顯示一次性通知:

public function updateAction()
{
    // ... 表單處理
    if ($form->isValid()) {
        $this->get('session')->setFlash('notice', '變更已儲存!');
        return $this->redirect($this->generateUrl(...));
    }
    return $this->render(...);
}

模板中顯示:

{% if app.session.hasFlash('notice') %}
    
{{ app.session.flash('notice') }}
{% endif %}

Response 物件詳解

// 簡單回應
$response = new Response('Hello ' . $name, 200);

// JSON 回應
$response = new Response(json_encode(array('name' => $name)));
$response->headers->set('Content-Type', 'application/json');

headers 屬性為 HeaderBag 物件,提供豐富的標頭操作方法。

Request 物件常用操作

$request = $this->getRequest();

$request->isXmlHttpRequest();           // 判斷 AJAX 請求
$request->getPreferredLanguage(array('en','fr'));
$request->query->get('page');           // 獲取 $_GET 參數
$request->request->get('page');         // 獲取 $_POST 參數

總結

Symfony2 控制器設計遵循單一職責原則,透過基礎類提供的輔助方法大幅簡化常見任務。開發者可專注於業務邏輯,而將 HTTP 細節交由框架處理。無論是渲染模板、重定向、轉發、錯誤處理還是 Session 管理,都有標準化的解決方案。

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