【发布时间】: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