运行数据库种子时(以及其他控制台命令),我遇到了命名冲突。
我的所有模型都存储在app/Models
目录中,并且位于App\Models
命名空间中。此目录中有一个名为Model.php
的基本模型,它扩展了laravel基本模型。
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model as BaseModel;
abstract class Model extends BaseModel {}
我的一些模型扩展了这个基类,例如
<?php namespace App\Models;
class User extends Model {}
我的一些模型直接扩展了雄辩的模型,例如
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Sport extends Model {}
当我的应用程序通过http访问时,这可以正常工作,并且没有命名冲突。但是,当我尝试运行控制台命令时,例如db:seed
,我收到以下错误:
PHP Fatal error: Cannot use Illuminate\Database\Eloquent\Model as Model because the name is already in use in /home/vagrant/Code/wisletics/app/Models/Sport.php on line 3
我最初的猜测是laravel以某种方式编译种子文件,这导致了冲突。有没有人有任何想法,或者还有其他人遇到过这个问题吗?
答案 0 :(得分:3)
问题出在
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Sport extends Model {}
这会产生一个问题,因为你已经拥有App\Models\Model
,现在当PHP尝试获取Sport
(Model
)的父类时,它无法确定你是否真的要求App\Models\Model
或Illuminate\Database\Eloquent\Model
。
这个问题可以通过实际更改为:
来解决<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model as BaseModel;
class Sport extends BaseModel {}
更新:为什么在播种时会看到这个? Laravel 5使用PSR-4,在请求之前它不会加载任何模型,这在您尝试运行SportTableSeeder
时会发生。
答案 1 :(得分:1)
我快速玩弄了这个。我认为你是对的,种子似乎将它们组合在一起,这就是给你命名冲突。
但我想补充一点,我认为你的命名惯例有点令人困惑。在相同类型的Eloquent类中的不同上下文中使用Model
似乎并不理想。
为什么不将Model
重命名为BaseModel
- 并将Eloquent类保留为Model
。然后,有人会看到你的代码如何运作,这是显而易见的。
修改:问题是DatabaseSeeder
班级使用Illuminate\Database\Eloquent\Model
。然后它执行$this->call('Your Seed File Here')
- 动态解析并在其自身内调用类 - 这意味着其他类在DatabaseSeeder
类的上下文中运行。
这会产生命名空间问题 - 导致种子失败。
您可能可以这样做:
<?php
use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
class DatabaseSeeder extends Seeder {
public function run()
{
Model::unguard();
$sport = new SportTableSeeder;
$sport->run();
}
}
注意 - 使用此方法
将丢失控制台上的种子输出