PHP 怎么请求路由

wen PHP项目 2

本文目录导读:

PHP 怎么请求路由

  1. 基础环境配置(Apache/Nginx)
  2. 原生 PHP 实现路由
  3. 面向对象实现路由(推荐)
  4. PHP 框架实现(Laravel 示例)
  5. 完整示例:一个简单的 REST 风格路由系统
  6. 最佳实践建议
  7. 查询现有框架

在 PHP 中“请求路由”通常有两种理解:前端路由(通过 URL 重写实现)和后端路由(框架或原生实现),下面我分别讲解。

基础环境配置(Apache/Nginx)

Apache (.htaccess)

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

Nginx

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

原生 PHP 实现路由

方式1:基于 URL 参数(简单版)

<?php
// index.php
$path = $_GET['url'] ?? '/';
// 路由表
$routes = [
    '/' => 'home',
    '/users' => 'user_list',
    '/users/create' => 'user_create',
];
if (isset($routes[$path])) {
    // 处理逻辑
    echo "执行: " . $routes[$path];
} else {
    http_response_code(404);
    echo "404 Not Found";
}

方式2:正则匹配(更灵活)

<?php
// index.php
$path = $_GET['url'] ?? '/';
// 去掉尾部的斜杠
$path = rtrim($path, '/');
$routes = [
    '/^\/users$/' => ['controller' => 'UserController', 'method' => 'index'],
    '/^\/users\/(\d+)$/' => ['controller' => 'UserController', 'method' => 'show'],
    '/^\/users\/create$/' => ['controller' => 'UserController', 'method' => 'create'],
];
foreach ($routes as $pattern => $handler) {
    if (preg_match($pattern, $path, $matches)) {
        $controller = new $handler['controller']();
        array_shift($matches); // 移除第一个匹配项(整个匹配串)
        // 调用控制器方法,并传递参数
        call_user_func_array([$controller, $handler['method']], $matches);
        exit;
    }
}
http_response_code(404);
echo "页面不存在";

面向对象实现路由(推荐)

创建 Router 类

<?php
// Router.php
class Router {
    private $routes = [];
    // 注册 GET 路由
    public function get($path, $callback) {
        $this->routes['GET'][$path] = $callback;
    }
    // 注册 POST 路由
    public function post($path, $callback) {
        $this->routes['POST'][$path] = $callback;
    }
    // 解析当前请求
    public function resolve() {
        $method = $_SERVER['REQUEST_METHOD'];
        $path = $_GET['url'] ?? '/';
        // 去除路径中的查询字符串
        $path = explode('?', $path)[0];
        foreach ($this->routes[$method] ?? [] as $route => $handler) {
            // 支持 {id} 这样的参数占位符
            $pattern = preg_replace('/\{([a-zA-Z0-9_]+)\}/', '([^/]+)', $route);
            $pattern = "@^" . $pattern . "$@";
            if (preg_match($pattern, $path, $matches)) {
                array_shift($matches);
                return call_user_func_array($handler, $matches);
            }
        }
        // 没有匹配的路由
        http_response_code(404);
        echo "404 Not Found";
    }
}

使用 Router

<?php
// index.php
require_once 'Router.php';
$router = new Router();
// 定义路由
$router->get('/', function() {
    echo '首页';
});
$router->get('/users', function() {
    echo '用户列表';
});
$router->get('/users/{id}', function($id) {
    echo "查看用户 ID: $id";
});
$router->post('/users', function() {
    echo '创建新用户';
});
// 启动路由
$router->resolve();

PHP 框架实现(Laravel 示例)

Laravel 路由

// routes/web.php
use App\Http\Controllers\UserController;
Route::get('/', function () {
    return view('welcome');
});
Route::get('/users', [UserController::class, 'index']);
Route::get('/users/{id}', [UserController::class, 'show']);
Route::post('/users', [UserController::class, 'store']);
Route::put('/users/{id}', [UserController::class, 'update']);
Route::delete('/users/{id}', [UserController::class, 'destroy']);
// 带中间件的路由
Route::middleware(['auth'])->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
    Route::resource('posts', PostController::class);
});

Laravel 路由参数和条件

// 必选参数
Route::get('/user/{id}', function ($id) {
    return "User ID: $id";
});
// 可选参数
Route::get('/search/{query?}', function ($query = null) {
    return $query ? "搜索: $query" : "默认搜索";
});
// 正则约束
Route::get('/user/{id}', function ($id) {
    return "User $id";
})->where('id', '[0-9]+');
// 命名路由
Route::get('/profile', function () {
    return '个人中心';
})->name('profile');
// 使用命名路由生成 URL
echo route('profile');

完整示例:一个简单的 REST 风格路由系统

<?php
// index.php - 完整路由系统
class SimpleRouter {
    private static $routes = [];
    public static function add($method, $path, $callback) {
        self::$routes[] = [
            'method' => strtoupper($method),
            'path' => $path,
            'callback' => $callback
        ];
    }
    public static function get($path, $callback) {
        self::add('GET', $path, $callback);
    }
    public static function post($path, $callback) {
        self::add('POST', $path, $callback);
    }
    public static function dispatch() {
        $requestMethod = $_SERVER['REQUEST_METHOD'];
        $requestPath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        foreach (self::$routes as $route) {
            if ($route['method'] === $requestMethod) {
                $pattern = preg_replace('/\{(\w+)\}/', '([^/]+)', $route['path']);
                $pattern = str_replace('/', '\/', $pattern);
                if (preg_match('/^' . $pattern . '$/', $requestPath, $matches)) {
                    array_shift($matches);
                    return call_user_func_array($route['callback'], $matches);
                }
            }
        }
        http_response_code(404);
        echo json_encode(['error' => 'Not Found']);
    }
}
// 定义路由
SimpleRouter::get('/api/users', function() {
    echo json_encode(['status' => 'success', 'data' => ['user1', 'user2']]);
});
SimpleRouter::get('/api/user/{id}', function($id) {
    echo json_encode(['status' => 'success', 'user_id' => $id]);
});
SimpleRouter::post('/api/login', function() {
    $data = json_decode(file_get_contents('php://input'), true);
    echo json_encode(['status' => 'login success', 'data' => $data]);
});
// 启动路由
SimpleRouter::dispatch();

最佳实践建议

  1. 使用分层的目录结构

    /
    ├── public/
    │   └── index.php     # 入口文件
    ├── app/
    │   ├── Controllers/  # 控制器
    │   ├── Models/       # 模型
    │   ├── Views/        # 视图
    │   └── Middleware/   # 中间件
    ├── routes/
    │   └── web.php       # 路由定义
    └── config/
     └── config.php    # 配置文件
  2. 缓存路由表提升性能(生产环境)

  3. 验证和过滤路由参数

  4. 使用中间件处理认证、日志、CORS等

查询现有框架

  • Laravel - 重型框架,功能最全
  • Symfony - 企业级框架
  • ThinkPHP - 国内流行的中文框架
  • FastRoute - 高性能路由库
  • Phalcon - C 扩展实现,性能极高

如果项目较小,直接使用上述原生实现即可;大型项目建议使用成熟框架来管理路由。

抱歉,评论功能暂时关闭!