monken/ci4-route-attributes

使 CodeIgniter4 路由器支持使用 PHP8 属性语法自动绑定控制器方法和控制器。

v1.0.0 2022-02-12 15:33 UTC

This package is auto-updated.

Last update: 2024-09-12 21:16:20 UTC


README

Latest Stable Version Total Downloads Latest Unstable Version License PHP Version Require

您可以使用此库通过注释定义控制器路由设置,使 CodeIgniter4 能够定义路由设置。

中文手册

快速演示

namespace App\Controllers;

use monken\Ci4RouteAttributes\Route;

class Ci4Controller extends BaseController
{
    #[Route(path: 'attr/route', methods: ["get"])]
    public function hello()
    {
        return "PHP8Attributes";
    }
}

使用 #[Route(path: 'attr/route', methods: ["get"])] 的定义,表示在您的路由配置中完成了相同的设置

$routes->get('attr/route', 'App\Controllers\Ci4Controller::hello');

此库将智能地将您的控制器和路由自动连接起来,这意味着您可以通过 /attr/route 的路径访问 Ci4Controller 中的 hello 方法。

安装指南

需求

  1. CodeIgniter 框架 4
  2. Composer
  3. PHP8↑

Composer 安装

使用 Composer 在项目根目录下下载所需依赖库。

composer require monken/ci4-route-attributes

使用库内置命令初始化所需文件。

php spark route-attr:init

上述命令将对我们的项目进行更改。

  1. app/Config 将有一个 RouteAttributes.php 配置文件,您可以通过此文件调整库的执行设置。它看起来像这样
    <?php
    
    namespace Config;
    
    use CodeIgniter\Config\BaseConfig;
    
    class RouteAttributes extends BaseConfig
    {
    
        /**
        * Routes are automatically registered only if this is set to `true`
        *
        * @var boolean
        */
        public bool $enabled = true;
    
        /** 
        * autoscan namespaces
        *
        * @var array<string>
        */
        public array $controllerNamespaces = [
            "App\Controllers"
        ];
    
        /**
        * Generate production environment route definition file path
        *
        * @var string
        */
        public string $routeDefinitionFilePath = WRITEPATH . 'cache';
    
        /**
        * Whether to use pre-generated route definition files in production.
        * Note that when this option is set to `true`, controller files will not be automatically
        * scanned in production environment. You must use `route-attr:make` command to generate
        * route definition files to improve performance in production environment.
        *
        * @var boolean
        */
        public bool $productionUseDefinitionFile = true;
    }
  2. 自动将库所需的事件写入 app/Config/Events.php 文件的端点,该事件将在 CodeIgniter4 初始化时使用,自动注册路由。该命令将写入以下内容
    Events::on('pre_system', function(){
        \monken\Ci4RouteAttributes\RouteAttributes::runHandler();
    });

说明

简而言之,此库是利用 PHP8 属性功能在 CodeIgniter4 路由器下的一种表示方式,它仅对一些 CodeIgniter4 路由器方法提供了一些映射和封装。除此之外,没有其他额外功能。

通过自动扫描控制器内的注释,连接路由和操作,让您能够直接编写路由规则,并以方便的方式维护控制器和路由之间的关系。

生产和开发环境

当您在 CodeIgniter4 框架的开发环境下使用此库时,每次请求发生时,它将重新分析所有控制器类,并处理相应的路由属性。这种策略可以为开发带来最大便利,路由属性的更改将立即生效。然而,在生成环境中,这种策略将导致相当大的性能损失。因此,我们的库提供了一种类似缓存的机制来降低生成环境中的性能损失。

配置文件

您可以在 app/Config/RouteAttributes.php 中找到两个可调整的变量,分别是 routeDefinitionFilePathproductionUseDefinitionFile

您可以使用 routeDefinitionFilePath 来定义生成环境配置文件的存储位置,默认为 project_root/writable/cache

您可以将productionUseDefinitionFile设置为truefalse来定义是否在生产环境中激活路由属性定义文件,以实现最佳性能。如果设置为false,则每次请求生产环境时,都会重新扫描,并在控制器中处理路由属性。

生成路由属性定义文件

您可以使用以下命令生成您的路由属性定义文件,以降低性能损失:

php spark route-attr:make

上述命令将在routeDefinitionFilePath中定义的路径下生成一个RouteAttributesDefinition文件。

更新路由属性定义文件

有两种方法可以更新生产环境中的路由属性定义文件:

  1. 再次运行php spark route-attr:make,新内容将直接覆盖旧内容。
  2. 删除RouteAttributesDefinition文件,如果库找不到该文件,它将自动扫描并生成路由属性定义文件。

路由

您可以按照如下方式注册您的路由:

namespace App\Controllers;

use monken\Ci4RouteAttributes\Route;

class Ci4Controller extends BaseController
{
    #[Route(path: 'attr/route', methods: ["get"])]
    public function hello()
    {
        return "PHP8Attributes";
    }
}

在此示例中,Path表示调用此控制器方法的实际路径,而method将期望您传递一个字符串数组,包括访问此控制器方法所需的HTTP动词。

根据CodeIgniter4的路由全局选项,您可以使用以下动词:addgetpostputheadoptionsdeletepathcli。您可以声明多个动词,以在同一个path下实现不同method之间的切换,并访问相同的控制器效果。

选项

您可以将选项数组传递进去,以对路由进行特殊调整,库不会对您的选项进行任何处理或判断,这意味着您必须查阅CodeIgniter4文档来编写正确的选项。通常,此参数将如下所示:

#[Route(path: 'attr/route', methods: ["get"], options:[
    'filter' => 'auth',
    'hostname' => 'accounts.example.com'
])]

忽略分组

如果您正在使用RouteGroup来统一配置同一控制器下的路由,但想要将其中一个单独设置,而不扩展RouteGroup。您可以设置此参数为true,使路由成为一个独立的任务,如下所示:

#[Route(path: 'attr/route', methods: ["get"], ignoreGroup: true)]

占位符

您只需关注path中的占位符配置,库将确定您控制器中的参数数量并完成正确的路由设置。

<?php

namespace App\Controllers;

use monken\Ci4RouteAttributes\Route;

class Ci4Controller extends BaseController
{
    #[Route(path: 'test/(:segment)/(:segment)/(:segment)', methods: ["get"])]
    public function hello($a, $b, $c)
    {
        echo $a . '<br>';
        echo $b . '<br>';
        echo $c . '<br>';
    }

}

等于

$route->get('test/(:segment)/(:segment)/(:segment)', 'App\Controllers\Ci4Controller::hello/$1/$2/$3');

单方法声明多个路由

如果您需要,也可以将多个路由设置绑定到单个方法。

namespace App\Controllers;

use monken\Ci4RouteAttributes\Route;

class Ci4Controller extends BaseController
{
    #[Route(path: 'attr/route', methods: ["get"])]
    #[Route(path: 'hello/msg', methods: ["get"])]
    public function hello()
    {
        return "PHP8Attributes";
    }
}

通过上述设置,无论访问attr/route还是hello/msg,它们都指向同一个Ci4Controller的hello方法。

RESTful 路由

CodeIgniter4为您提供了方便的RESTful模式,您可以继承相关类以快速实现RESTful设计模式。此库也提供相关模式,帮助您快速将控制器转换为RESTful路由。

资源路由

<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourceController;
use monken\Ci4RouteAttributes\RouteRESTful;

#[RouteRESTful(name: 'api/user', type: 'resource')]
class UserApi extends ResourceController
{
    //...
}

等于

$routes->resource('api/user', [
    "controller" => 'App\Controllers\UserApi'
]);

name表示资源名称,也可以声明为路径。在type上有两个可用的选项,分别命名为resourcepresenter

展示者路由

您可以根据需要调整type的值,将RouteRESTful转换为Presenter Route模式。

<?php

namespace App\Controllers;

use CodeIgniter\RESTful\ResourcePresenter;
use monken\Ci4RouteAttributes\RouteRESTful;

#[RouteRESTful(name: 'user', type: 'presenter')]
class User extends ResourcePresenter
{
    //...
}

等于

$routes->presenter('user', [
    "controller" => 'App\Controllers\User'
]);

您可以根据需要调整RouteRESTful的type,通过设置您的ResourceRoutePresenterRoute

websafe

此选项仅在type采用resource时才会激活。它将在路由的options中添加websafe => 1,使其可用于HTML表单。

#[RouteRESTful(name: 'api/user', websafe: true)]

only

您可以使用only选项来限制只生成您提到的路由。此参数仅接受一个数组,由方法名称组成。

#[RouteRESTful(name: 'api/user', only: [
    'index', 'show'
])]

有关可接受的方法名称,请参阅我们的文档

except

您可以使用except来移除某些路由的生成,此参数只接受一个数组,由方法名组成。

#[RouteRESTful(name: 'api/user', except: [
    'new', 'edit'
])]

有关可接受的方法名称,请参阅我们的文档

占位符

如果您的API需要资源ID,默认情况下将使用(:segment)占位符。但您也可以传递placeholder参数来对其进行更改

#[RouteRESTful(name: 'api/user', placeholder: ':(num)')]

选项

通过传递选项数组到特定于RESTful路由的修订,库不会对您传递的选项进行任何判断。

需要注意的一点是,如果使用了诸如websafeonlyexceptplaceholder之类的参数,那么库将自动将您传递的内容与options数组组合。如果有重复声明,则参数内容将被关注。

您必须参考CodeIgniter4文档来编写正确的选项。通常,此参数的使用方法如下所示

#[RouteRESTful(name: 'api/user', placeholder: ':(num)', options: [
    'filter' => 'auth'
])]

忽略分组

如果您正在使用RouteGroup来统一配置同一控制器下的路由,但想要将其中的一个单独设置而不扩展RouteGroup。您可以设置此参数为true

#[RouteRESTful(name: 'api/user', ignoreGroup: true)]

路由分组

通常,您不会希望重新配置重复的path,例如/api/v1。因此,您可以使用RouteGroup将相同的pathoptions统一应用于类下的所有路由设置。

<?php

namespace App\Controllers;

use monken\Ci4RouteAttributes\Route;
use monken\Ci4RouteAttributes\RouteGroup;

#[RouteGroup(name: '/route/testgroup', options: ['filter' => 'auth'])]
class Group extends BaseController
{

    #[Route(path: 'getindex', methods: ['get'])]
    public function index()
    {
        return "hi";
    }

    #[Route(path: 'get/something', methods: ['get'])]
    public function somefunction()
    {
        return "something";
    }
}

上级设置等于

$routes->group(
    '/route/testgroup',
    ['filter' => 'auth'],
    function ($routes) {
        $routes->get('getindex', 'App\Controllers\Group ::index');
        $routes->get('get/something', 'App\Controllers\Group ::somefunction');
    }
);

路由环境

您可以为特定环境创建特殊路由,例如,开发环境中的路由在生产环境和预发布环境中不可用。您可以通过在类中声明RouteEnvironment来实现此要求。

<?php

namespace App\Controllers;

use monken\Ci4RouteAttributes\Route;

#[RouteEnvironment(type: "development")]
class EnvRoute extends BaseController
{

    #[Route(path:'dev/tool', methods:['cli'])]
    public function devToolMethod()
    {
        return "tool msg";
    }

    #[Route(path:'dev/page', methods:['get'])]
    public function devPageMethod()
    {
        return "page msg";
    }

上级设置等于

$routes->environment('development', function ($routes) {
    $routes->cli('dev/tool', 'App\Controllers\EnvRoute::devToolMethod');
    $routes->get('dev/page', 'App\Controllers\EnvRoute::devPageMethod');
});

如果需要,RouteEnvironment也可以与RouteGroup一起使用

<?php

namespace App\Controllers;

use monken\Ci4RouteAttributes\Route;
use monken\Ci4RouteAttributes\RouteGroup;

#[RouteEnvironment(type: "development")]
#[RouteGroup('/dev')]
class EnvRoute extends BaseController
{

    #[Route(path:'tool', methods:['cli'])]
    public function devToolMethod()
    {
        return "tool msg";
    }

    #[Route(path:'page', methods:['get'])]
    public function devPageMethod()
    {
        return "page msg";
    }

上级设置等于

$routes->environment('development', function ($routes) {
    $routes->group(
        '/dev',
        function ($routes) {
            $routes->cli('tool', 'App\Controllers\EnvRoute::devToolMethod');
            $routes->get('page', 'App\Controllers\EnvRoute::devPageMethod');
        }
    );
});