【问题标题】:Subclassing Migrator not working for namespaced migration子类化迁移器不适用于命名空间迁移
【发布时间】:2015-07-03 13:09:12
【问题描述】:

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

Laravel 迁移器不适用于命名空间迁移。在这种情况下,最好的办法是继承并替换 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

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

【问题讨论】:

  • 这是一个很长的问题。为什么要让它变得困难并首先创建自定义迁移?
  • 做工匠转储自动加载
  • 正如我所指出的,我运行了 dump-autoload 并得到了想要的结果;问题似乎是当 Laravel 尝试解析迁移文件中的类名时 - 它忽略了子类应该处理的命名空间。
  • 好的,此时我已经确定我可能没有注册 MigrationServiceProvider。当我弄清楚如何适当地处理它(我显然只希望它应用于命名空间迁移)时,我会在这里发布。

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


【解决方案1】:

好的,我已经完成了这项工作。事实证明,Medium.com 文章假设您只知道将他谈到的文件放在哪里,而我不知道。我做了几处更改,现在一切正常:

  1. 我创建了一个新的appTruancy\providers 子文件夹,并将其添加到composer.json
  2. 我将Migrator.phpMigrationServiceProvider.php 都移到了新文件夹中
  3. 我将这两个文件中的命名空间更改为 Truancy\Providers 以匹配目录结构
  4. 我在appTruancy\config\app.phpproviders 数组中添加了'Truancy\Providers\MigrationsServiceProvider'
  5. 我在migration 文件中的Schema 前面添加了一个\ 以引用基本命名空间。
  6. 我运行了 dump-autoload 来更新类映射

这是我不能 100% 确定所有更改都是必需的情况之一,但布局确实有意义,所以我很满意。所以,简而言之,如果你想命名你的迁移,你需要继承 Migrator 类,如上面列出的 Medium.com 文章中所述,但你需要在config\app 中注册服务提供者,确保两个文件中的类名是一致的。

【讨论】:

    猜你喜欢
    • 2016-03-14
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    • 2017-05-05
    • 2020-02-23
    • 2021-06-11
    相关资源
    最近更新 更多