首頁 >後端開發 >php教程 >PHP 設計模式:前端控制器

PHP 設計模式:前端控制器

Barbara Streisand
Barbara Streisand原創
2024-12-23 20:07:11605瀏覽

PHP Design Patterns: Front Controller

前端控制器是Web應用程式開發中用於集中請求處理的設計模式。所有請求都透過單一中央控制器路由,負責將它們定向到適當的元件或模組,而不是為系統的不同部分設定多個入口點。

它是如何運作的

  1. 單一入口點: 所有 HTTP 請求都使用 Web 伺服器設定(例如,Apache 的 .htaccess 或 Nginx 中的路由規則)重定向到單一檔案(通常為 index.php)。
  2. 路由:前端控制器分析 URL 並決定應該執行哪一部分程式碼。這可以手動實現或使用路由庫/框架來實現。
  3. 委託:根據路由,前端控制器將請求委託給適當的控制器(類別或方法),該控制器處理資料並回傳回應。
  4. 回應: 控制器產生一個回應(通常是 HTML 或 JSON),發送回瀏覽器或用戶端。

優點

  • 集中化:所有傳入的應用程式流都透過單點處理,從而更輕鬆地管理和追蹤請求。
  • 靈活性:輕鬆整合全域功能,如驗證、權限控制、日誌或錯誤處理。
  • 復用性:通用邏輯可以集中在前端控制器中,減少重複。
  • 可維護性:集中化簡化了更新,例如新增新的路由或控制器。

例子

目錄結構

/app
    /Controllers
        HomeController.php
        ProductController.php
    /Core
        Entrypoint.php
/config
    routes.php
/public
    index.php
/vendor
composer.json

自動載入

要實現PSR-4,請在專案根目錄中建立composer.json檔案:

{
    "autoload": {
        "psr-4": {
            "App\": "app/"
        }
    }
}

執行以下命令來產生自動載入器:

composer dump-autoload

重定向請求

apache(.htaccess)

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [L]

nginx

server {
    listen 80;
    server_name example.com;

    root /path/to/your/project/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; # Adjust for your PHP version
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~* \.(css|js|jpg|jpeg|png|gif|ico|woff|woff2|ttf|svg|eot|ttc|otf|webp|avif)$ {
        expires max;
        log_not_found off;
    }

    location ~ /\.ht {
        deny all;
    }
}

儲存設定檔後,重新啟動 Nginx 以套用變更

sudo systemctl reload nginx

控制器

HomeController

namespace App\Controllers;

class HomeController {
    public function index(): void {
        echo "Welcome to the home page!";
    }
}

產品控制器

namespace App\Controllers;

class ProductController
{
    public function list(): void
    {
        echo "Product list.";
    }
}

入口點

namespace App\Core;

class Entrypoint {

    public function __construct(private array $routes) {
    }

    public function handleRequest(): void {
        $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

        if (isset($this->routes[$uri])) {
            $route = $this->routes[$uri];
            $controller = new $route['controller'];
            $method = $route['method'];

            if (method_exists($controller, $method)) {
                $controller->$method();
            } else {
                $this->sendResponse(500, "Method not found.");
            }
        } else {
            $this->sendResponse(404, "Page not found.");
        }
    }

    private function sendResponse(int $statusCode, string $message): void {
        http_response_code($statusCode);
        echo $message;
    }
}

配置

路線

$routes = [
    '/' => [
        'controller' => 'HomeController',
        'method' => 'index'
    ],
    '/products' => [
        'controller' => 'ProductController',
        'method' => 'list'
    ]
];

索引(前控制器)

require_once __DIR__ . '/../vendor/autoload.php';

use App\Core\Entrypoint;

$routes = require __DIR__ . '/../config/routes.php';

$entrypoint = new Entrypoint($routes);
$entrypoint->handleRequest();

結果

此實作:

  • 使用前端控制器模式集中請求處理。
  • 將路由邏輯封裝在 Entrypoint 類別中。
  • 採用 PSR-4 進行自動載入和更好的程式碼組織。
  • 使用 Nginx 設定進行無縫設定。

以上是PHP 設計模式:前端控制器的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn