📜  如何在路由中提供可选参数 - PHP (1)

📅  最后修改于: 2023-12-03 14:52:58.700000             🧑  作者: Mango

如何在路由中提供可选参数 - PHP

在 PHP 中,我们可以使用路由来指定特定的 URL 地址和对应的处理函数。有时候,我们需要在路由中提供一些可选参数,以便处理器函数能够根据参数的不同值执行不同的操作。本篇文章将介绍如何在 PHP 中实现路由中的可选参数。

定义路由

在 PHP 中,一般使用第三方路由库来定义路由。这里以 FastRoute 为例。首先需要安装 FastRoute:

composer require nikic/fast-route

然后在代码中定义路由:

<?php
require_once 'vendor/autoload.php';

$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $r) {
    $r->addRoute('GET', '/user/{id:\d+}[/{name}]', function($id, $name = null) {
        echo "User $id";
        if ($name) {
            echo " ($name)";
        }
    });
});

// Fetch method and URI from somewhere
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];

// Strip query string (?foo=bar) and decode URI
if (false !== $pos = strpos($uri, '?')) {
    $uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);

$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
    case FastRoute\Dispatcher::NOT_FOUND:
        // ... 404 Not Found
        break;
    case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
        $allowedMethods = $routeInfo[1];
        // ... 405 Method Not Allowed
        break;
    case FastRoute\Dispatcher::FOUND:
        $handler = $routeInfo[1];
        $vars = $routeInfo[2];
        [$controllerName, $methodName] = explode('@', $handler);
        $controller = new $controllerName();
        call_user_func_array([$controller, $methodName], array_values($vars));
        // ... call $handler with $vars
        break;
}

在上面的代码中,我们定义了一个路由 /user/{id:\d+}[/{name}],其中 id 是必须的参数,而 name 是可选的参数。我们用正则表达式 /:d+ 指定了 id 参数的格式,即数字。对于可选参数,我们在参数名后面加上方括号和参数名,以指定该参数是可选的。

获取参数值

在上面的代码中,当路由被匹配成功后,我们可以通过 $vars 数组来获取路由中的参数值。如果一个参数是可选的,但实际 URL 中没有传递该参数值,则该参数的值为 null。我们可以根据参数值的不同执行不同的操作。

$r->addRoute('GET', '/user/{id:\d+}[/{name}]', function($id, $name = null) {
    echo "User $id";
    if ($name) {
        echo " ($name)";
    }
});

在上面的代码中,我们根据 $name 参数是否为空来判断是否需要输出用户昵称。

总结

本篇文章介绍了如何在 PHP 中实现路由中的可选参数。我们使用了 FastRoute 这个第三方路由库,并给出了相应的代码示例。希望对你有所帮助!