mrf0o / php-router
一个类似于Laravel但又简单的PHP路由实现
Requires
- php: >=8.0
Requires (Dev)
- phpunit/phpunit: 9.6.x-dev
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类的静态方法,因此您可以使用这些方法中的任何一个来替换get
:post
、put
、patch
和delete
。
请确保使用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
辅助函数,这应该是全局可用的 - 路由约束的辅助方法
- 中间件
- 速率限制