devamirul / p-router
一个简单、轻量级且功能强大的PHP路由器,具有中间件和控制器等丰富功能,是一个简单而实用的路由类。深受Laravel处理路由方式的影响。
Requires
- php: >=8.00
- ext-json: *
README
_____ _____ _
| __ \ | __ \ | |
| |__) ______ | |__) |___ _ _| |_ ___ _ __
| ___/ |______| | _ // _ \| | | | __/ _ \ '__|
| | | | \ \ (_) | |_| | || __/ |
|_| |_| \_\___/ \__,_|\__\___|_|
一个简单、轻量级且功能强大的PHP路由器,具有中间件和控制器等丰富功能。深受Laravel处理路由方式的影响。
功能
- 支持
GET
POST
PUT
PATCH
和DELETE
HTTPS 动词 - 路由器支持的请求方法有: -
get()
post()
put()
patch()
delete()
match()
any()
- 命名路由
- 参数的正则表达式约束
- 回退方法
- 中间件
- CSRF 保护
- 控制器
- 方便管理请求的简单方法
- 辅助方法
- 命令行界面(CLI)
目录
安装
可以使用Composer进行安装。
composer require devamirul/p-router
将以下脚本添加到 composer.json
文件中
"autoload": { "psr-4": { "App\\": "app/" } }, "scripts": { "start": [ "php -S 127.0.0.1:8000" ], "middleware": "cd vendor/devamirul/p-router/src/CLI && php createMiddleware.php && cd -", "controller": "cd vendor/devamirul/p-router/src/CLI && php createController.php && cd -", "app": "cd vendor/devamirul/p-router/src/CLI && php createApp.php && cd -" }
运行以下命令
composer dump-autoload
创建 app
文件夹。
composer app
启动PHP服务器。
composer start
示例
基本路由
$router->get('/', function () { echo 'welcome to p-route'; })->name('home');
或
$router->get('/', [WelcomeController::class, 'index'])->name('home');
动态路由
$router->get('/users/:id', function(){ // })->where(['id' => '^\d+$'])->name('user');
中间件
$router->get('/users/:id', function(){ // })->middleware('auth')->where(['id' => '^\d+$'])->name('user');
如果您想进行方法链,可以这样做。
目录
app/config
:此文件夹包含系统配置文件。仅在配置文件中更改。
app/Middlewares
:在此文件夹中创建您的自定义中间件。
app/Controllers
:在此文件夹中创建您的自定义控制器。
路由
可用路由方法
路由器允许您注册响应任何HTTP动词的路由
$router->get($uri, $callback); $router->post($uri, $callback); $router->put($uri, $callback); $router->patch($uri, $callback); $router->delete($uri, $callback); $router->match($uri, $callback); $router->any($uri, $callback);
基本路由
路由接受一个URI和一个闭包或数组,提供了一种非常简单和表达性的方法来定义路由和行为,无需复杂的路由配置文件。
- 首先创建index.php文件。
- 定义应用程序根路径。
- 需要供应商自动加载文件。
- 创建
router
单例实例。 - 定义路由。
- 通过
run()
方法运行应用程序。
<?php /** * Define root directory. */ define('APP_ROOT', dirname(__FILE__)); /** * Require composer autoloader. */ require __DIR__ . '/vendor/autoload.php'; // Get singleton route instance. $router = Devamirul\PRouter\Router::singleton(); // Define routes. $router->get('/greeting', function () { return 'Hello World'; }); // Resolve and run application. $router->run(); ?>
或创建一个单独的route.php
文件,并在index.php
文件中包含该文件。
首先创建route.php或根据您的选择命名文件
<?php // Define routes $router->get('/greeting', function () { return 'Hello World'; }); $router->fallback(function () { return 'Fallback route'; }); ?>
在index.php
文件中包含route.php
/** * Require composer autoloader. */ require __DIR__ . '/vendor/autoload.php'; // Get singleton route instance. $router = Devamirul\PRouter\Router::singleton(); // Require route.php require_once './route.php'; // Resolve and run application. $router->run();
让我们讨论第二个参数。第二个参数接受一个闭包或键值对数组。数组中的'key'将是一个类,'value'将是类的某个方法,该方法将由类调用。
use App\Controllers\WelcomeController; $router->get('/', [WelcomeController::class, 'index'])->name('home');
使用return代替echo。
// Right way. $router->get('/greeting', function () { return 'Hello World'; }); // wrong way. $router->get('/greeting', function () { echo 'Hello World'; });
命名路由
命名路由允许方便地生成特定路由的URL或重定向。您可以通过在路由定义上链接name方法来指定路由的名称
路由名称应该是唯一的。
$router->get('/user/profile', function () { // ... })->name('profile');
生成命名路由的URL
一旦为给定的路由分配了名称,您可以通过toRoute()
进行重定向。
return toRoute('profile');
如果命名路由定义了参数,您可以将参数作为toRoute
函数的第二个参数传递。给定的参数将自动插入到生成的URL的正确位置。
$router->get('/user/:id/profile', function () { // ... })->name('profile'); return toRoute('profile', ['id' => 1]);
如果您在数组中传递额外的参数,这些键/值对将自动添加到生成的URL的查询字符串中
$router->get('/user/:id/profile', function () { // ... })->name('profile'); return toRoute('profile', ['id' => 1, 'photos' => 'yes']);
如果您在路由中使用星号(*),则不能通过toRoute()
调用它。
路由参数
必需参数
有时您需要在您的路由中捕获URI的部分。例如,您可能需要从URL中捕获用户ID。您可以通过$request->getParam()
方法获取它。
$router->get('/user/:id', function (Request $request) { return 'User ' . $request->getParam('id'); });
您可以根据路由的需要定义任意多的路由参数
$router->get('/posts/:post/comments/:comment', function (Request $request) { //Get all parameters array. return 'User ' . $request->getParam(); //Get specific parameter. return 'User ' . $request->getParam('post'); });
路由参数始终以冒号':'开头,应包含字母数字字符。
参数
在您的路由回调或控制器中自动获取'Request'实例。
在回调中
$router->get('/user/:id', function (Request $request) { return 'User ' . $request->getParam('id'); });
在控制器中
$router->get('/user/:id', [UserController::class, 'index']);
namespace App\Http\Controllers; use Devamirul\PhpMicro\core\Foundation\Application\Request\Request; use Devamirul\PhpMicro\core\Foundation\Controller\BaseController; class UserController extends BaseController { public function index(Request $request) { return 'User ' . $request->getParam('id'); } }
可选参数
有时您可能需要指定一个可能不在URI中存在的路由参数。您可以通过在参数后放置问号?
来实现。
请注意,可选参数始终放在URL的末尾。
$router->get('/user/:name?', function () { // });
正则表达式约束
您可以通过在路由实例上使用where
方法来限制您的路由参数的格式。该where()
方法接受一个正则表达式作为参数,该参数确定参数应该如何分隔。该"where()"方法将接受路由器动态参数的序列化参数。
$router->get('/user/:id', function () { // ... })->where(['id' => '^\d+$']);
可选参数的正则表达式约束
$router->get('/user/:name?', function () { // })->where(['name' => '^[a-zA-Z ]*$']);
多个可选参数的正则表达式约束
$router->get('/profile/:id/user/:name?', function () { // })->where(['id' => '^\d+$', 'name' => '^[a-zA-Z ]*$']);
匹配和任何方法
有时您可能需要注册一个响应多个HTTP动词的路由。您可以使用match方法来实现,或者甚至可以使用any方法注册一个响应所有HTTP动词的路由。
$router->match(['get', 'post'], '/', function () { // ... }); $router->any('/', function () { // ... });
路由通配符
您可以使用星号来使用动态路由。
$router->get('admin/*', function () { // ... });
在上面的示例中,您可以在admin/
之后动态使用任何路径。星号用作通配符,匹配任何字符组合。
中间件
app/Middlewares
:中间件提供了一种方便的机制来检查和过滤进入您应用程序的HTTP请求。
预定义的中间件文件包括:AuthMiddleware.php
、CsrfMiddleware.php
默认情况下,您将在handle方法中获取一个请求实例。
创建中间件
要创建新的中间件,请使用composer middleware
命令。
composer middleware
命令行界面将询问您中间件名称,您输入一个名称。它将自动将"Middleware"添加到您提供的名称中。例如,您想要创建一个名为"example"的中间件。那么您的中间件类将是ExampleMiddleware.php
namespace App\Middlewares; use Devamirul\PRouter\Interfaces\Middleware; use Devamirul\PRouter\Request\Request; class AuthMiddleware implements Middleware { /** * Handle an incoming request. */ public function handle(Request $request): void { // } }
例如,该框架包含一个中间件,用于验证您的应用程序用户是否已认证。如果用户未认证,中间件将重定向用户到您的应用程序登录页面。然而,如果用户已认证,中间件将允许请求继续进入应用程序。
public function handle(Request $request): void { if (!isset($_SESSION['user'])) { redirect('/login'); } return; }
添加中间件
创建中间件后,将其添加到'app/config/middleware.php'文件中的中间件数组中。将您自己的中间件添加到此列表,并分配您选择的别名。
'middleware' => [ 'csrf' => Devamirul\PRouter\Middleware\Middlewares\CsrfMiddleware::class, 'auth' => App\Middlewares\AuthMiddleware::class ],
如果您想要将中间件分配给特定路由,您可以在定义路由时调用中间件方法。一旦定义了中间件别名,您在将中间件分配给路由时使用该别名。
Router::get('/users/:id', function(){ // })->middleware('auth');
如果您想一次分配多个中间件,您可以这样做。
Router::put('/users/:id', function(){ // })->middleware(['auth','csrf']);
设置默认中间件
如果您想默认将某些中间件分配给Https动词,这非常简单,定义的中间件将在处理该https方法请求时运行。
打开app/config/middleware.php
'get' => [], 'post' => [ 'csrf' ], 'put' => [ 'csrf' ], 'patch' => [ 'csrf' ], 'delete' => [ 'csrf', 'auth' ],
CSRF 保护
在任何您在应用程序中定义的“POST”、“PUT”、“PATCH”或“DELETE”HTML表单中,都应该包含一个隐藏的CSRF _token字段,以便CSRF保护中间件可以验证请求。否则,请求将被拒绝。为了方便,您可以使用setCsrf()
函数生成隐藏的token输入字段。
<form method="POST" action="/profile"> <?=setCsrf()?> ... </form>
控制器
app/Controllers
:控制器响应用户操作(提交表单、显示用户、查看数据等)。控制器是扩展BaseController类的类。
默认情况下,您将在每个方法中获取请求实例。
创建控制器
要创建新的控制器,请使用composer controller
命令。
composer controller
命令行界面将询问您控制器名称,您输入一个名称。它将自动将“Controller”添加到您提供的名称。例如,您想创建一个名为“example”的控制器。那么您的控制器类将是ExampleController.php
。
namespace App\Controllers; use Devamirul\PRouter\Request\Request; use Devamirul\PRouter\Controller\BaseController; class UserController extends BaseController { /** * Show user. */ public function show(Request $request) { return 'user name -' . $request->input('name'); } }
请求
框架的Request类提供了一个面向对象的方式来与您的应用程序正在处理的当前HTTP请求交互,以及检索随请求提交的输入。
访问请求
您可以通过请求辅助函数获取请求实例。
// Get all input data. request()->all();
// Get all input data. request()->input(); // Get input data specified by key, return default data if key not found. request()->input('name', 'default'); // Get input data specified by key. request()->only('name', 'email'); // Get path. request()->path(); // Get all query. request()->query(); // Get query data specified by key. request()->query('name'); // Get current method. request()->method(); // Get all input data. request()->all(); // Get dynamic params. request()->getParam(); // Get specific param. request()->getParam('id');
您还将获得方法。
isGet()
isPost()
isPut()
isPatch()
isDelete()
处理HTML视图内容文件
您可以从控制器或回调函数中轻松查看html内容
。
简单地将您想查看的文件`require`。
$router->get('/', function () { require_once './home.php'; });
在内容文件中
<body> <h1>Home Page</h1> </body>
您可以在内容文件中轻松查看数据。
$router->get('/', function (Request $request) { $name = 'Amirul islam'; require_once './home.php'; });
在内容文件中
<body> <h1>Welcome Mr <?= $name ?> </h1> <?php foreach ($request->input() as $value) { echo $value; } ?> </body>
处理表单
<form action="/login" method="POST" class="mt-5"> <?=setCsrf()?> <div class="mb-3"> <label for="exampleInputEmail" class="form-label">Email address</label> <input type="email" name="email" class="form-control" id="exampleInputEmail" aria-describedby="emailHelp"> <div id="emailHelp" class="form-text"> <?= errors('email')?> </div> </div> <div class="mb-3"> <label for="exampleInputPassword" class="form-label">Password</label> <input type="password" name="password" class="form-control" id="exampleInputPassword"> <div id="emailHelp" class="form-text"> <?= errors('password')?> </div> </div> <button type="submit" class="btn btn-primary">Login</button> </form>
方法字段
由于HTML表单不能发出PUT、PATCH或DELETE请求,您需要添加一个隐藏的_method
字段来模拟这些HTTP动词。setMethod()
Blade指令可以为您创建此字段。
<form> <?=setMethod('delete')?> ... </form>
辅助方法
目录
通用辅助函数
获取配置数据
config('app', 'timezone');
详细查看数据后退出代码
dd([1,2,3]);
详细查看数据
dump();
表单辅助函数
设置新的CSRF值
setCsrf();
示例
<form> <?=setCsrf()?> </form>
检查CSRF是否有效,返回bool
isCsrfValid();
设置表单方法,如put/patch/delete
setMethod();
示例
<form> <?=setMethod('delete')?> </form>
请求辅助函数
获取请求实例
request();
示例
request()->input();
响应辅助函数
重定向链接
return redirect('/redirect-link');
通过路由名称查找路由并重定向此路由
return toRoute('users');