我在运行数据库种子(以及其他控制台命令)时遇到了命名冲突。
我的所有模型都存储在app/Models
目录中,并且位于App'Models
命名空间中。该目录中有一个称为CCD_ 3的基础模型,它扩展了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以某种方式编译了种子文件,这导致了冲突。有人有什么想法吗,或者其他人已经遇到这个问题了吗?
问题在
<?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,在请求之前,它不会加载任何Model,这是在您尝试运行SportTableSeeder
时发生的。
我对此进行了快速处理。我认为你是对的,种子似乎把它们组合在一起,这给了你命名冲突。
但我想补充一点,我认为你的命名惯例有点令人困惑。在相同类型的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();
}
}
注意-使用此方法