首页 >后端开发 >php教程 >PHP 设计模式:前端控制器

PHP 设计模式:前端控制器

Barbara Streisand
Barbara Streisand原创
2024-12-23 20:07:11660浏览

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