devamirul/p-router

一个简单、轻量级且功能强大的PHP路由器,具有中间件和控制器等丰富功能,是一个简单而实用的路由类。深受Laravel处理路由方式的影响。

安装: 29

依赖项: 0

建议者: 0

安全: 0

星标: 22

关注者: 0

分支: 3

开放问题: 2

类型:

v1.0.11 2023-11-11 05:41 UTC

This package is not auto-updated.

Last update: 2024-09-24 21:01:56 UTC


README

  _____            _____             _
 |  __ \          |  __ \           | |
 | |__)   ______  | |__) |___  _   _| |_ ___ _ __
 |  ___/ |______| |  _  // _ \| | | | __/ _ \ '__|
 | |              | | \ \ (_) | |_| | ||  __/ |
 |_|              |_|  \_\___/ \__,_|\__\___|_|

一个简单、轻量级且功能强大的PHP路由器,具有中间件和控制器等丰富功能。深受Laravel处理路由方式的影响。

功能

  • 支持 GET POST PUT PATCHDELETE 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和一个闭包或数组,提供了一种非常简单和表达性的方法来定义路由和行为,无需复杂的路由配置文件。

  1. 首先创建index.php文件。
  2. 定义应用程序根路径。
  3. 需要供应商自动加载文件。
  4. 创建router单例实例。
  5. 定义路由。
  6. 通过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.phpCsrfMiddleware.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');