【问题标题】:Naming Conflict in Laravel 5 Database SeedingLaravel 5 数据库播种中的命名冲突
【发布时间】:2015-04-21 13:38:46
【问题描述】:

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

我的所有模型都存储在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 {}

我的一些模型直接扩展了 eloquent 模型,例如

<?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 以某种方式编译种子文件,这导致了冲突。有没有人有任何想法,或者其他人已经遇到过这个问题?

【问题讨论】:

  • 编译后的文件在存储目录storage/framework/compiled.php
  • 我刚刚想到 - 你能发布你的数据库种子文件吗?
  • @satrun77 我根本看不到那个文件。

标签: php namespaces laravel-5 laravel-seeding


【解决方案1】:

我很快就解决了这个问题。我认为你是对的,种子似乎将它们组合在一起,这给你带来了命名冲突。

但我想补充一点,我认为您的命名约定有点混乱。在同一类型的 Eloquent 类中的不同上下文中使用 Model 似乎并不理想。

为什么不将您的 Model 重命名为 BaseModel - 并将 Eloquent 类保留为 Model。这样一来,看了你的代码的人就会立刻明白它是如何工作的。

编辑:所以问题是DatabaseSeeder 类使用Illuminate\Database\Eloquent\Model。然后它执行$this-&gt;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();    
    }
}

注意 - 使用此方法会丢失控制台上的种子输出

【讨论】:

  • 这不是use 的重点吗?我并不太关心命名约定。 laravel 以前使用的是BaseController,但是在 L5 升级中它被重命名为Controller,并且它把Illuminate\Routing\Controller 导入为BaseController,所以我的命名是符合的。
  • 所以我也这么认为,所以我在数据库播种器中为我的Illuminate\Database\Eloquent\Model 起了别名,认为这可以解决问题,但没有运气。您的新建议很有趣,但正如您所说,我丢失了输出,并且还编写了 2 倍的代码行数。
【解决方案2】:

问题出在

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Sport extends Model {}

这会产生一个问题,因为您已经拥有App\Models\Model,现在当 PHP 尝试获取 Sport (Model) 的父类时,它无法确定您实际上是在请求 App\Models\Model 还是 @987654327 @。

这个问题可以通过实际改成:

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model as BaseModel;

class Sport extends BaseModel {}

更新:为什么你在播种时看到这个?好吧,Laravel 5 使用 PSR-4,它在请求之前不会加载您的任何模型,当您尝试运行 SportTableSeeder 时会发生这种情况。

【讨论】:

  • 我相信你对这个答案是正确的,但是关于为什么它只在控制台中访问而不是通过 HTTP 时会导致错误的任何想法?我觉得它应该双向失败。
  • 这可能是由于这个错误bugs.php.net/bug.php?id=66773 OpCache 通常在 CLI 中被禁用。
猜你喜欢
  • 2016-02-13
  • 1970-01-01
  • 2018-12-11
  • 2015-09-25
  • 2016-02-10
  • 1970-01-01
  • 2015-04-13
相关资源
最近更新 更多