You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel9自定义包数据校验与错误时禁用插件实现方案

Laravel 9 自定义包数据校验与功能控制实现方案

一、核心数据校验类封装

先把你的自定义校验逻辑整理成标准可复用类:

// packages/companyname/Mypackage/src/Validators/DataValidator.php
namespace Companyname\Mypackage\Validators;

use Illuminate\Support\Facades\DB;

class DataValidator
{
    public function validate(): array
    {
        $errors = [];

        // 示例:检测关联表必填字段缺失
        $invalidRecords = DB::table('related_table')
            ->whereNull('required_field')
            ->count();
            
        if ($invalidRecords > 0) {
            $errors[] = "关联表存在 {$invalidRecords} 条缺少必填字段的记录";
        }

        // 追加你的其他校验逻辑...

        return $errors;
    }
}

二、后台触发校验流程

方式1:Artisan命令触发(兼顾CLI与后台调用)

  1. 创建校验命令类:
// packages/companyname/Mypackage/src/Console/Commands/ValidatePackageData.php
namespace Companyname\Mypackage\Console\Commands;

use Companyname\Mypackage\Validators\DataValidator;
use Illuminate\Console\Command;

class ValidatePackageData extends Command
{
    protected $signature = 'mypackage:validate';
    protected $description = '校验自定义包关联表数据逻辑';

    public function handle(DataValidator $validator)
    {
        $errors = $validator->validate();

        if (empty($errors)) {
            $this->info('数据校验通过,无逻辑错误');
            return 0;
        }

        $this->error('数据校验发现以下错误:');
        foreach ($errors as $error) {
            $this->line("- {$error}");
        }
        return 1; // 返回非0状态码,供脚本判断结果
    }
}
  1. 在服务提供者注册命令:
// packages/companyname/Mypackage/src/Providers/MypackageProvider.php
public function register()
{
    $this->commands([
        \Companyname\Mypackage\Console\Commands\ValidatePackageData::class,
    ]);
}
  1. 后台页面触发:添加HTTP路由调用命令
// 可放在包的路由文件或主项目后台路由中
Route::post('/admin/mypackage/validate', function () {
    $exitCode = Artisan::call('mypackage:validate');
    $output = Artisan::output();

    return response()->json([
        'status' => $exitCode === 0 ? 'success' : 'error',
        'message' => $output
    ]);
})->middleware('auth');

方式2:后台控制器直接调用校验类

如果不需要CLI支持,可直接在控制器中执行校验:

// packages/companyname/Mypackage/src/Http/Controllers/AdminValidatorController.php
namespace Companyname\Mypackage\Http\Controllers;

use Companyname\Mypackage\Validators\DataValidator;
use Illuminate\View\View;

class AdminValidatorController extends Controller
{
    public function index(): View
    {
        $validator = new DataValidator();
        $errors = $validator->validate();

        return view('mypackage::admin.validate', compact('errors'));
    }
}

注册路由并创建对应的Blade视图展示错误即可。

三、安装/迁移/自动加载时显示错误

1. Composer脚本触发校验

在自定义包的composer.json中添加脚本,绑定到安装和自动加载刷新事件:

{
    "scripts": {
        "post-install-cmd": [
            "@php artisan mypackage:validate"
        ],
        "post-dump-autoload": [
            "@php artisan mypackage:validate"
        ]
    }
}

兼容环境未初始化场景:在校验类开头添加数据库连接判断

// DataValidator.php 的 validate 方法开头
if (!DB::connection()->getPdo()) {
    return ['数据库连接未就绪,无法执行数据校验'];
}

2. 迁移/填充后触发校验

在包的迁移、填充文件末尾追加校验逻辑:

// 迁移文件示例:packages/companyname/Mypackage/database/migrations/xxxx_xx_xx_create_mytable_table.php
public function up()
{
    Schema::create('mytable', function (Blueprint $table) {
        // 表结构定义
    });

    // 迁移完成后执行校验
    $validator = new \Companyname\Mypackage\Validators\DataValidator();
    $errors = $validator->validate();

    if (!empty($errors)) {
        foreach ($errors as $error) {
            \Illuminate\Support\Facades\Log::error('Mypackage迁移后数据错误:'.$error);
            if (app()->runningInConsole()) {
                echo "⚠️ Mypackage数据校验错误:{$error}\n";
            }
        }
    }
}

填充文件的run方法可参照上述写法添加校验。

四、存在错误时禁用插件功能

1. 自动设置功能开关

在服务提供者中执行校验并写入配置:

// packages/companyname/Mypackage/src/Providers/MypackageProvider.php
public function boot()
{
    $this->loadMigrationsFrom(__DIR__.'/../database/migrations');

    // 加载包配置文件
    $this->mergeConfigFrom(
        __DIR__.'/../config/mypackage.php', 'mypackage'
    );

    // 执行校验并设置启用状态
    $validator = new \Companyname\Mypackage\Validators\DataValidator();
    $errors = $validator->validate();
    
    config(['mypackage.enabled' => empty($errors)]);

    // 记录错误日志
    if (!empty($errors)) {
        foreach ($errors as $error) {
            \Illuminate\Support\Facades\Log::error('Mypackage数据校验失败:'.$error);
        }
    }
}

包配置文件示例:

// packages/companyname/Mypackage/config/mypackage.php
return [
    'enabled' => true, // 默认启用,由服务提供者动态覆盖
];

2. 功能入口添加禁用判断

所有包功能入口(控制器、门面、服务等)添加校验:

// 控制器示例
public function feature()
{
    if (!config('mypackage.enabled')) {
        abort(403, '插件数据存在逻辑错误,功能已禁用');
    }
    // 正常业务逻辑
}

// 门面示例
class MypackageFacade extends Facade
{
    protected static function getFacadeAccessor()
    {
        if (!config('mypackage.enabled')) {
            throw new \RuntimeException('插件数据存在逻辑错误,功能已禁用');
        }
        return 'mypackage';
    }
}

// Blade视图示例
@if(config('mypackage.enabled'))
    <!-- 插件功能组件 -->
@else
    <div class="alert alert-danger">插件数据存在逻辑错误,功能已禁用</div>
@endif

3. 主项目判断插件可用性

主项目可直接调用校验类判断:

if (class_exists(\Companyname\Mypackage\Validators\DataValidator::class)) {
    $validator = new \Companyname\Mypackage\Validators\DataValidator();
    $errors = $validator->validate();
    $isMypackageEnabled = empty($errors);
} else {
    $isMypackageEnabled = false;
}

// 使用判断结果
if ($isMypackageEnabled) {
    // 启用插件相关逻辑
}

内容的提问来源于stack exchange,提问作者Petro Gromovo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:45:25