mrf0o/php-router

一个类似于Laravel但又简单的PHP路由实现

v1.0.2 2024-09-17 10:32 UTC

This package is auto-updated.

Last update: 2024-09-18 00:48:25 UTC


README

这个路由器旨在帮助您轻松高效地处理PHP应用程序中的HTTP请求和响应。它受到流行的Laravel框架的启发,旨在提供类似的经验和功能。

入门

安装

您可以使用Composer通过运行以下命令来安装 MrF0o/php-router

composer require mrf0o/php-router

设置

安装完包后,您可以通过php命令行或通过Apache之类的反向代理服务器来运行您的应用程序。

方法1:PHP CLI

例如,在项目的根目录中创建一个index.php文件(您可以命名任何您想要的名称)并包含以下内容

<?php

include_once "vendor/autoload.php";

use Mrfoo\PHPRouter\Router;

Router::get('/', function() {
    echo 'Hello World!';
});

Router::run();
php -S localhost:8888 index.php

此命令将在8888端口上运行您的应用程序。如果一切正常,您应该在浏览器中访问 https://:8888 来显示文本“Hello World”。

方法2:反向代理

在这里,您可以找到可以用于此路由器正确运行的rewrite规则所需的.htaccess文件示例。您可以使用之前方法中的相同示例代码,并确保将文件放置在Apache期望的文档根目录下(通常为htdocs)。

Apache默认使用index.php作为主文件,因此它将默认提供它。但是,如果您想在项目中全局使用此路由器,希望所有流量都指向index.php,即使用户尝试访问项目中的不同文件夹。

<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
    Options -MultiViews
</IfModule>

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ ^$1 [N]

RewriteCond %{REQUEST_URI} (\.\w+$) [NC]
RewriteRule ^(.*)$ public/$1

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php
</IfModule>

请注意,重写规则中的public/目录。此规则将所有资产请求重定向到public文件夹。如果您愿意,可以将此文件夹重命名为其他名称,例如assets。只需确保相应地更新重写规则即可。

注意:您需要将index.php更改为包含Router::run()调用的文件。

重要

此路由器目前不支持子文件夹。您可能需要在.htaccess中进行额外配置才能使其工作。

路由器类

安装完成后,您可以通过包含Router类来开始使用路由器。例如,此路由将在访问/hello时触发

use Mrfoo\PHPRouter\Router;

Router::get('/hello', function () {
    echo  '<h1>hello there</h1>';
});

Router::run();

您可以看到每个请求都表示为Router类的静态方法,因此您可以使用这些方法中的任何一个来替换getpostputpatchdelete

请确保使用run静态方法运行路由器。

路由参数

要捕获URL中的段,您可以使用路由参数,这些参数将按顺序传递到处理函数中。

Router::get('/hello/{name}', function ($name) {
    echo  '<h1>hello '.$name.'</h1>';
});

尚未实现可选参数,因此此路由只有在存在参数{name}时才会匹配,否则将返回404错误

正则表达式约束

有时,您可能需要使用正则表达式约束参数,您可以使用Route实例上的where方法来完成此操作。

Router::get('/user/{name}', function ($name) {
    // ...
})->where('name', '[A-Za-z]+');

Router::get('/user/{id}/{name}', function  (string  $id, string  $name) {
    // ...
})->where(['id'  =>  '[0-9]+', 'name'  =>  '[a-z]+']);

命名路由

您可以使用Route实例上的name方法为您的路由命名,这将使您稍后在代码中使用route辅助方法引用路由变得更加容易。

Router::get('/user/profile', function  () {
    // ...
})->name('profile');

分组路由

此外,您可以使用路由器类的group方法创建路由组,每个在回调中注册的路由将共享传递给group方法的属性。

Router::group(['prefix' => '/user'], function () {
    // here all routes will be prefixed with /user
    Router::get('/update', fn () => die('not implemented')); /* /user/update */
});

路由重定向

您可以使用 Router 类的 redirect 方法将路由重定向到另一个路由。

Router::redirect('/old', '/new');

默认情况下,重定向将是一个 302 重定向,但您可以通过传递状态码作为第三个参数来更改它。

Router::redirect('/old', '/new', 301);

或者,如果您想要永久重定向,可以使用 permanentRedirect 方法,这将发送一个 301 重定向。

Router::permanentRedirect('/old', '/new');

生成URL

您可以使用 route 辅助方法生成您路由的 URL,此方法接受路由名称和要传递给路由的参数数量。

Router::get('/user/{id}', function ($id) {
    // ...
})->name('user.profile');

$url = route('user.profile', 1);
// $url = 'http://example.com/user/1'

中间件

中间件是过滤请求在它们到达路由处理程序之前的一种好方法,在这个路由库中,中间件以覆盖 \Mrfoo\PHPRouter\Middleware 类中的 handle 方法的类表示。

<?php
namespace Middlewares;

use Mrfoo\PHPRouter\Core\Middleware;

class AuthMiddleware extends Middleware
{
    public function handle()
    {
        if (!isset($_SESSION['user_id'])) {
            // redirect to login page
            header('Location: /login');
            exit;
        }
    }
}

handle 方法将在路由处理程序之前被调用,因此您可以在需要时进行任何检查并重定向用户。

然后您可以使用中间件在您的路由中像这样使用

Router::get('/user/profile', function () {
    // ...
})->name('user.profile')->middleware(AuthMiddleware::class);

并且您可以将多个中间件分配给一个路由,如下所示

Router::get('/user/profile', function () {
    // ...
})->name('user.profile')->middleware([AuthMiddleware::class, AnotherMiddleware::class]);

您可以通过覆盖 terminate 方法在路由处理程序调用后进行任何清理。

<?php
namespace Middlewares;

use Mrfoo\PHPRouter\Core\Middleware;

class AuthMiddleware extends Middleware
{
    public function handle()
    {
        if (!isset($_SESSION['user_id'])) {
            // redirect to login page
            header('Location: /login');
            exit;
        }
    }

    public function terminate()
    {
        // do some cleanup
    }
}

快速示例

<?php
include './vendor/autoload.php';
use Mrfoo\PHPRouter\Router;
use Controllers\UserController;

Router::get('/greet', function () {
    echo 'hello everyone';
})->name('greeting');

Router::post('/user/create', function () {
    // ...
    $id = $_POST['user_id']; // make sure to sanitize your inputs!
})->name('user.create');

Router::patch('/user/profile', [UserController::class, 'update'])->name('user.profile.update');

// make it bun dem!
Router::run();

这里我使用了 UserController 类作为示例,来展示除了回调函数之外还可以使用路由处理程序的其他约定。

待办事项

  • 路由分组
  • 路由重定向
  • route 辅助函数,这应该是全局可用的
  • 路由约束的辅助方法
  • 中间件
  • 速率限制