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

时间:2015-02-20 00:05:07

标签: php namespaces laravel-5 laravel-seeding

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

我的所有模型都存储在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以某种方式编译种子文件,这导致了冲突。有没有人有任何想法,或者还有其他人遇到过这个问题吗?

2 个答案:

答案 0 :(得分:3)

问题出在

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Sport extends Model {}

这会产生一个问题,因为你已经拥有App\Models\Model,现在当PHP尝试获取SportModel)的父类时,它无法确定你是否真的要求App\Models\ModelIlluminate\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();    
    }
}

注意 - 使用此方法

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