Laravel 5数据库种子中的命名冲突


Naming Conflict in Laravel 5 Database Seeding

我在运行数据库种子(以及其他控制台命令)时遇到了命名冲突。

我的所有模型都存储在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试图获得SportModel)的父类时,它无法决定您实际上是要求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();    
    }
}

注意-使用此方法

,您将丢失控制台上的种子输出