simanx/spes

There is no license information available for the latest version (v0.0.1) of this package.

simple and easy framework

v0.0.1 2023-04-25 02:32 UTC

This package is not auto-updated.

Last update: 2025-07-15 20:14:34 UTC


README

一个简单(simple and easy)的基于Loader驱动的模块化框架

使用条件

  • PHP >= 8.1
  • Laravel >= 10.0

安装

使用composer

composer require simanx/spes

如果你想要对spes的配置进行修改,可以发布配置文件到项目配置中

php artisan vendor:publish --provider="Simanx\Spes\Providers\SpesServiceProvider"

得益于laravel包发现机制,SpesServiceProvider将被自动注册,如果你不希望在项目中使用该机制,则需要在config/app.php的providers数组中添加\Simanx\Spes\Providers\SpesServiceProvider::class

'providers' => [
    // ...
    /*
     * Package Service Providers...
     */
    \Simanx\Spes\Providers\SpesServiceProvider::class,

    // ...
]

特征

  1. 基于Loader驱动的路由、事件、命令和定时任务(默认使用Attribute标记进行加载)
  2. 模块化管理(旨在在一个文件夹中完成对应模块尽可能多的内容编辑)

使用

使用前请先查看spes的配置内容

Loader

spes提供了基于Attribute标记的Loader

路由Attribute(Router, Get, Post, Patch, Put, Delete)

Router Attribute有三个参数,分别指定路由的前缀,路由名前缀和路由组的共有中间件

Get等对应请求方法的Attribute的4个参数分别表示路由uri,路由名称,中间件和路由其他额外内容

注意:只在类层面注册Router,spes不会进行路由注册,Router只指定控制器中所有路由的基础内容,目的是为了防止路由重复指定和模块的区分,对应Controller的共有方法上注册Get或其他RequestMethod方法的Attribute才会进行路由注册

namespace App\Modules\Auth\Controllers;

use Simanx\Spes\Attribute\Route\Attributes\Get;
use Simanx\Spes\Attribute\Route\Attributes\Post;
use Simanx\Spes\Attribute\Route\Attributes\Router;

#[Router('/auth', 'auth', 'web')]
class AuthController {
    #[Get('/login', 'index')]
    public function index()
    {
        return view('auth::index');
    }
    
    #[Post('/login', 'login')]
    public function login(LoginRequest $request) {
        // ...
    }
}

权限Attribute(Can)

Can可以为路由增加权限检测中间件, 其中权限使用PermissionManager进行管理,spes的权限与模块化深度集成,对于非模块化的路由权限,可以使用PermissionManager的add进行添加

#[Router('/blog', 'blog', 'web'), Can('blog')]
class BlogController {
    #[Get('/', 'index'), Can('index')]
    public function index()
    {
        return view('blog::index');
    }

    #[Post('/create', 'create'), Can('create')]
    public function create() {
        // ...
    }
}

spes也封装了纯净的request(Dto),只需要将Request类继承Simanx\Spes\Dto\Dto,设置请求对应参数内容,Spes便会从请求中获取对应参数并赋值对应Dto中的共有属性

你也可以在Dto的共有属性上指定数据类型以指导Dto解析器将对应参数

class LoginRequest {
    // Validation(string $rule, string $message): 设置字段的验证规则,Spes将会自动解析并进行validate调用
    #[\Simanx\Spes\Validation\Attributes\Validation('required|max:16', '账号必填且长度最大为16')]
    public string $account; // 指定数据类型(内置类型|Dto)以引导Dto解析器将参数解析为指定类型

    #[\Simanx\Spes\Validation\Attributes\Validation('required|max:16', '密码必填且长度最大为16')]
    public string $password;
}

#[Router('/auth')]
class AuthController {
    #[Post('/login')]
    public function login(LoginRequest $request) {
        // $request->account;
        // $request['account'];
        // $request->toArray();
        // $request->toJson();
    }
}

事件Attribute(Listen)

spes会进行对应Listener进行监听,并且根据第二个参数指定的参数进行优先级排序(值越大越先监听)

use Simanx\Spes\Attribute\Event\Attributes\Listen;
#[Listen(SomeEvent::class), Listen(SomeEvent2::class, 999)]
class SomeEventListener {
    public function handle() {
        
    }
}

Artisan命令Attribute(ArtisanCommand)

spes会自动进行对应command的注册

#[ArtisanCommand]
class CreateUserCommand extends Command {
    protected $signature = 'app:create-user';
    protected $description = '...';
    public function handle() {
        // ...
    }
}

Crontab Attribute(Cron)

spes会对对应的cron进行定时任务注册(cron的类必须是一个command)

#[Cron('* * * * *')]
class SomeCronCommand extends Command {
    // ...
}

自定义Loader

你也可以轻易地自定义Loader

假设你想从对应文件夹下面的route.php中进行路由的创建,你可以使用如下方法创建

创建加载器继承 Simanx\Spes\Attribute\Loader 并且重写load方法

class MyRouteLoader extends \Simanx\Spes\Attribute\AttributeLoader {
    public function load() {
        foreach($this->files() as $file) {
            if (! ($this->app instanceof CachesRoutes && $this->app->routesAreCached())) {
                require $file->getRealPath();
            }
        }
    }
}

将RouteAttributeLoader在spes配置文件中进行注册

// config/spes.php
return [
    // ...
    'loaders' => [
        MyRouteLoader::class  => [
            'path'   => [
                app_path('Http/Routes/')
            ],
            'name' => 'route.php'
        ],
    ],
    // ...
]

模块化

框架实现了简单的项目模块化管理,默认以 app/Modules/ 作为项目模块的根目录,你可以在spes配置文件中修改对应文件夹及其对应文件夹类型映射

spes将模块根目录下的一级目录名作为模块名,下面这个文件结构将作为两个模块(Auth和User),模块下的文件夹分别管理模块的部分内容(Controllers管理控制器,Commands管理模块特有命令等)

  • app
    • Modules
      • Auth
        • Controllers
        • Listeners
        • Commands
        • Components
        • Views
          • login.blade.php
        • Schedules
      • User

有些应用只提供api访问,而不需要对应view和component,则可以在spes配置文件中将view设置为false,spes将不会进行view和component的注册

默认,spes会对模块中的部分文件夹进行Attribute扫描,如:对Controllers下的对应类进行Router Attribute和对应请求方法的Attribute进行扫描,注册对应路由

// app/Modules/Auth/AuthController.php

#[Router('/auth', middleware: 'web')]
class AuthController
{
    #[Get('/login', 'login')]
    public function index()
    {
        return view('auth::login'); // 返回Auth模块下的 Views/login.blade.php
    }
    
    // ...
}

命令行支持

spes:make-module <module-name>  // 创建模块,将创建对应dirs

参与贡献

  1. Fork 本仓库
  2. 新建 Feat_xxx 分支
  3. 提交代码
  4. 新建 Pull Request