【问题标题】:Laravel calling seeder in subdirectory - Class not foundLaravel 在子目录中调用播种器 - 找不到类
【发布时间】:2022-01-16 18:29:18
【问题描述】:

几天前,当我尝试通过Artisan::call 在子目录中执行播种器时,Laravel(当前为 8.12 | php 7.4.14)开始抛出错误。

在 bash 上这个命令可以正常工作:

php artisan db:seed --class=Database\\Seeders\\Testing\\StagingTestDataSeeder

但我想将其执行为:

Artisan::call("db:seed --class=Database\\Seeders\\Testing\\StagingTestDataSeeder");

结果是:Target class [Database\\Seeders\\DatabaseSeedersTestingStagingTestDataSeeder] does not exist. 这是绝对正确的,因为参数中没有命名空间分隔符。因为参数中没有分隔符,getSeeder-方法只是将参数连接到数据库播种器的基本命名空间
(见下文if (strpos($class, '\\') === false) {)。

因为它适用于 bash,所以我认为命名空间或文件位置没有任何错误。
我在Illuminate\Database\Console\Seeds\SeedCommand.php::66中转储了一些数据

/**
     * Get a seeder instance from the container.
     *
     * @return \Illuminate\Database\Seeder
     */
    protected function getSeeder()
    {
        $class = $this->input->getArgument('class') ?? $this->input->getOption('class');
        dump($this->options());
        dump($this->arguments());
        dump($class);
        if (strpos($class, '\\') === false) {
            $class = 'Database\\Seeders\\' . $class;
        }

        if (
            $class === 'Database\\Seeders\\DatabaseSeeder' &&
            !class_exists($class)
        ) {
            $class = 'DatabaseSeeder';
        }

        return $this->laravel->make($class)
            ->setContainer($this->laravel)
            ->setCommand($this);
    }

打印这个:

array:10 [▼
  "class" => "DatabaseSeedersTestingStagingTestDataSeeder"
  "database" => null
  "force" => false
  "help" => false
  "quiet" => false
  "verbose" => false
  "version" => false
  "ansi" => null
  "no-interaction" => false
  "env" => null
]
array:2 [▼
  "command" => "db:seed"
  "class" => null
]
"DatabaseSeedersTestingStagingTestDataSeeder"

不知何故,转义的反斜杠无法到达 SeedCommand 类的 getSeeder 方法。
我知道我可以通过 require 使用纯 PHP 加载类,或者将深层命名空间添加到 composer.json。但由于这不是 laravel 的预期用途,我想弄清楚如何使用板载功能来做到这一点。

----稍后进行一些测试----

我发现我可以将类/命名空间值作为选项(使用--class=)以及参数(只是命名空间)传递给SeedCommand.php。所以 Artisan::call("db:seed Database\\\\Seeders\\\\Testing\\\\StagingTestDataSeeder"); 现在可以使用了。

有人可以解释那里发生了什么吗?我完全困惑为什么我需要通过双倍的反斜杠。似乎该论点被解释了两次。
SeedCommand 最近更新了吗?

【问题讨论】:

    标签: php laravel namespaces laravel-8 laravel-seeding


    【解决方案1】:

    使用

    Artisan::call('db:seed', ['--class' => Database\Seeders\Testing\StagingTestDataSeeder]);
    

    查看更多详情https://laravel.com/docs/8.x/artisan#programmatically-executing-commands

    【讨论】:

    • 好的,谢谢。这似乎行得通。但是你能解释一下为什么 bash 调用的语法在以编程方式调用时停止工作吗?
    • 我不知道需要检查
    猜你喜欢
    • 2023-01-12
    • 2018-12-27
    • 2021-04-09
    • 2015-07-22
    • 2013-05-25
    • 2014-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多