首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Laravel 7自定义Artisan命令抛出现有类的BindingResolutionException

Laravel 7自定义Artisan命令抛出现有类的BindingResolutionException
EN

Stack Overflow用户
提问于 2020-11-13 19:21:52
回答 1查看 249关注 0票数 0

我在Laravel 7中创建一个命令,在数据库/迁移和播种机中的文件夹中创建一些迁移。然后,它运行dumpAutoloads()以确保在autoload中注册所创建的迁移和种子器。然后,我的命令调用php迁移命令,并连续调用带有-class标志的php db:命令,只为创建的播种机种子。

在调用db:命令之前,一切都运行良好。播种机确实被创建了,但它一直抛给我下一个例外:

代码语言:javascript
复制
Illuminate\Contracts\Container\BindingResolutionException

Target class [StudentOperationTypesSeeder] does not exist

这显然只是一个示例,但我检查了创建的Seeder的名称与异常显示的名称完全相同,并且与之匹配。而且,在向我抛出这个异常之后,我自己运行db:命令,它就可以工作了!

这让我想,也许直到命令的进程完成或其他什么的时候,autoload类映射才被更新.我真的不知道。

我的代码如下:

TimeMachineGeneratorCommand.php

代码语言:javascript
复制
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;

class TimeMachineGeneratorCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'time-machine:generate {table_name}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Generates the tables and structure of a time machine for the given table.';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        // Convierte a snake case singular el nombre de la entidad.
        $entity = Str::singular(
            Str::snake(class_basename($this->argument('table_name')))
        );

        // Revisa que el nombre del modelo esté en el formato adecuado. 
        $modelName = Str::singular(
            Str::studly($this->argument('table_name'))
        );

        $seederClassName = "{$modelName}OperationTypesSeeder";

        // Crea las migraciones para la estructura de la máquina del tiempo.
        $this->createMigrations($entity);

        // Genera el Seeder del los operation types básicos.
        $this->createSeeder($seederClassName);

        // Para asegurarse que las migrations y el seeder está registrada en 
        // los class loaders se ejecuta el dump-autoload.
        $this->line("<fg=yellow>Dumping Autoloads...</>");
        $this->laravel->composer->dumpAutoloads();
        $this->info("Autoloads dumped.");

        // Ejecuta las migraciones.
        $this->call('migrate', [
            '--path' => '/database/migrations/'.Str::plural(Str::snake($modelName)).'/'
        ]);
        // Ejecuta el seeder recién creado.
        $this->call('db:seed', [
            '--class' => $seederClassName
        ]);
        
        (...) // <-- Some other code that isn't executed because of the exception
    }

    /**
     * Genera los archivos de código de las migraciones necesarias
     * para la estructura de la máquina del tiempo.
     */
    private function createMigrations($entity)
    {
        // Genera la migración para los tipos de operación de la entidad.
        $this->call('time-machine:operation-type-migration', [
            'entity' => $entity
        ]);

        // Genera la migración para los logs de la entidad.
        $this->call('time-machine:log-migration', [
            'entity' => $entity
        ]);

        // Genera la migración para los logs de la entidad.
        $this->call('time-machine:required-fields-migration', [
            'entity' => $entity
        ]);
    }

    /**
     * Crea el seeder de operationt types basado en el 
     * template diseñado para la máquina del tiempo.
     *
     * @param  string | $seederClassName | El nombre de la clase para el seeder.
     * @return void.
     */
    private function createSeeder($seederClassName)
    {
        $this->call('time-machine:seeder', [
            'name' => $seederClassName
        ]);

        // Agrega el seeder recién creado al DatabaseSeeder.php. 
        $this->updateDatabaseSeeder($seederClassName);
    }

    /**
     * Agrega el seeder recién creado al DatabaseSeeder.php.
     *
     * @var    $seederClassName.
     * @return void.
     */
    private function updateDatabaseSeeder($seederClassName)
    {
        $filePath = base_path().'\\database\\seeds\\DatabaseSeeder.php';

        // Lee el archivo del DataBaseSeeder.
        $seeder = file_get_contents($filePath);

        // Si el seeder no ha sido agregado ya al DatabaseSeeder.php...
        if(preg_match('/\$this\-\>call\('.$seederClassName.'\:\:class\)\;/', $seeder) == 0) {
            // Agrega el seeder recién creado.
            $newContent = preg_replace(
                '/public function run\(\)\s*\{/',
    "public function run()
    {
        \$this->call({$seederClassName}::class);", 
                
                $seeder, 1
            );
            
            // Guarda el contenido del archivo.
            file_put_contents($filePath, $newContent);

            $this->info('Seeder added to DatabaseSeeder.php.');
        } else {
            $this->error('Seeder is already in DataBaseSeeder.php.');
        }
    }
}

另外,这是我的composer.json的autoload部分(我读到可能有这样或那样的东西,我还是找不到解决问题的方法)。

代码语言:javascript
复制
    "autoload": {
        "psr-4": {
            "App\\": "app/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    },

StudentOperationTypesSeeder.php

代码语言:javascript
复制
<?php

use Illuminate\Database\Seeder;

class StudentOperationTypesSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $studentOperationType = new \App\StudentOperationType();
        $studentOperationType->description = "Created";
        $studentOperationType->save();

        $studentOperationType = new \App\StudentOperationType();
        $studentOperationType->description = "Updated";
        $studentOperationType->save();

        $studentOperationType = new \App\StudentOperationType();
        $studentOperationType->description = "Deleted";
        $studentOperationType->save();
    }
}

请帮帮忙。该命令成功地生成迁移和种子器,然后运行迁移,所有操作都完全按照预期进行,除了种子器之外,我还没有找到原因。

注意:我在TimeMachineGeneratorCommand.php函数中调用的其他命令是我创建的其他自定义命令,它们实际上只扩展了供应商的现有迁移命令,并将存根更改为自定义命令。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-17 15:56:27

我遵循了拉格提出的方法,发现了一些有用的东西。

我包括了生成的文件,在调用bd:命令之前添加了下一行代码,显然是在生成种子程序的行之后。

代码语言:javascript
复制
include base_path()."\\database\\seeds\\".$seederClassName.".php";

在这样做后,播种机将被正确地执行,整个命令就像预期的那样工作。

最后的句柄方法如下所示。

代码语言:javascript
复制
/**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        // Convierte a snake case singular el nombre de la entidad.
        $entity = Str::singular(
            Str::snake(class_basename($this->argument('table_name')))
        );

        // Revisa que el nombre del modelo esté en el formato adecuado. 
        $modelName = Str::singular(
            Str::studly($this->argument('table_name'))
        );

        $seederClassName = "{$modelName}OperationTypesSeeder";

        // Crea las migraciones para la estructura de la máquina del tiempo.
        $this->createMigrations($entity);

        // Genera el Seeder del los operation types básicos.
        $this->createSeeder($seederClassName);

        // Para asegurarse que las migrations y el seeder está registrada en 
        // los class loaders se ejecuta el dump-autoload.
        $this->line("<fg=yellow>Dumping Autoloads...</>");
        $this->laravel->composer->dumpAutoloads();
        $this->info("Autoloads dumped.");

        // Ejecuta las migraciones.
        $this->call('migrate', [
            '--path' => '/database/migrations/'.Str::plural(Str::snake($modelName)).'/'
        ]);

        include base_path()."\\database\\seeds\\".$seederClassName.".php";

        // Ejecuta el seeder recién creado.
        $this->call('db:seed', [
            '--class' => $seederClassName
        ]);
        
        (...) // <-- Some other code that isn't executed because of the exception
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64826837

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档