子类化Migrator不适用于命名空间迁移

时间:2015-04-24 19:22:15

标签: laravel-4 namespaces illuminate-container laravel-migrations

我有一些命名空间迁移,由于命名空间,我无法通过Class Not Found错误。 In an earlier questionAntonio Carlos Ribeiro声明:

  

Laravel migrator对命名空间迁移不起作用。在这种情况下,你最好的选择是继承和替换Migrator类,就像Christopher Pitt在他的博客文章中解释的那样:https://medium.com/laravel-4/6e75f99cdb0

我已经尝试过这样做(当然是composer dump-autoload),但我继续收到Class Not Found错误。我已将项目文件设置为

inetpub
|--appTruancy
   |--database
      |--2015_04_24_153942_truancy_create_districts.php
      |--MigrationsServiceProvider.php
      |--Migrator.php

迁移文件本身如下:

<?php

namespace Truancy;

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class TruancyCreateDistricts extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('districts', function($table) {
            $table->string('id')->unique()->primary()->nullable(false);
            $table->string('district');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('districts');
    }

}

Migrator.php如下:     

namespace Truancy;

use Illuminate\Database\Migrations\Migrator as Base;

class Migrator extends Base{
  /**
   * Resolve a migration instance from a file.
   *
   * @param string $file
   * @return object
   */
  public function resolve($file)
  {
    $file = implode("_", array_slice(explode("_", $file), 4));

    $class = "Truancy\\" . studly_case($file);

    return new $class;
  }
}

MigrationServiceProvider.php如下:

<?php

namespace Truancy;

use Illuminate\Support\ServiceProvider;

class TruancyServiceProvider extends ServiceProvider{
  public function register()
  {
    $this->app->bindShared(
      "migrator",
      function () {
        return new Migrator(
          $this->app->make("migration.repository"),
          $this->app->make("db"),
          $this->app->make("files")
        );
      }
    );
  }
}

autoload_classmap.php中生成的行符合预期:

'Truancy\\Migrator' => $baseDir . '/appTruancy/database/migrations/Migrator.php',
'Truancy\\TruancyCreateDistricts' => $baseDir . '/appTruancy/database/migrations/2015_04_24_153942_truancy_create_districts.php',
'Truancy\\TruancyServiceProvider' => $baseDir . '/appTruancy/database/migrations/MigrationsServiceProvider.php'

我正在呼叫php artisan migrate --path="appTruancy/database/migrations"并收到错误消息:

PHP Fatal error:  Class 'TruancyCreateDistricts' not found in
C:\inetpub\laravel\vendor\laravel\framework\src\Illuminate\Database
\Migrations\Migrator.php on line 297

我知道我必须做一些愚蠢的事情(我的本能是$class = "Truancy\\" . studly_case($file);在Migrator.php中是错误的),但是我无法拧开这个灯泡。 migrate命令显然是成功找到我的迁移文件,并且正确的类名在classmap中,因此它必须在从文件解析类名本身的过程中的某个地方,子类和替换应该解决该文件。关于我哪里出错的任何建议?

1 个答案:

答案 0 :(得分:0)

好的,我已经开始工作了。事实证明,Medium.com文章假设您只知道在哪里放置他所谈论的文件,而我没有。我做了几处修改,现在一切正常了:

  1. 我创建了一个新的appTruancy\providers子文件夹,并将其添加到composer.json
  2. 我已将Migrator.phpMigrationServiceProvider.php移至新文件夹
  3. 我将这两个文件中的命名空间更改为Truancy\Providers以匹配目录结构
  4. 我将'Truancy\Providers\MigrationsServiceProvider'添加到providers
  5. 中的appTruancy\config\app.php数组中
  6. 我在\文件的Schema前面添加了migration以引用基本命名空间。
  7. 我运行dump-autoload来更新classmap
  8. 这是我不能100%确定所有更改都是必需的情况之一,但布局确实有意义所以我很满意。因此,简而言之,如果您尝试命名迁移,则需要按照上面列出的Medium.com文章中的描述对Migrator类进行子类化,但是您需要在config\app中注册服务提供者,确保两个文件中的类名一致。