问题
I have some namespaced migrations, and I can't get past the Class Not Found errors due to namespacing. In an earlier question, Antonio Carlos Ribeiro stated:
Laravel migrator doesn't play nice with namespaced migrations. Your best bet in this case is to subclass and substitute the Migrator class, like Christopher Pitt explains in his blog post: https://medium.com/laravel-4/6e75f99cdb0.
I have tried doing so (followed by composer dump-autoload
, of course), but am continuing to receive Class Not Found errors. I've got the project files set up as
inetpub
|--appTruancy
|--database
|--2015_04_24_153942_truancy_create_districts.php
|--MigrationsServiceProvider.php
|--Migrator.php
The migration file itself is as follows:
<?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 is as follows:
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 is as follows:
<?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")
);
}
);
}
}
The lines generated in autoload_classmap.php are as expected:
'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'
I'm calling php artisan migrate --path="appTruancy/database/migrations"
and I receive the error:
PHP Fatal error: Class 'TruancyCreateDistricts' not found in
C:\inetpub\laravel\vendor\laravel\framework\src\Illuminate\Database
\Migrations\Migrator.php on line 297
I know I must be doing something dumb (my instinct is $class = "Truancy\\" . studly_case($file);
in Migrator.php is wrong), but I can't unscrew this lightbulb. The migrate command is obviously successfully finding my migrations file, and the correct classname is in the classmap, so it has to be somewhere in the process of resolving the classname itself from the file, which the subclass and substitution is supposed to address. Any suggestions as to where I've gone wrong?
回答1:
Ok, I've gotten this working. It turns out that the Medium.com article assumes you'd just know where to put the files he talks about, which I didn't. I've made several changes, and now everything is working correctly:
- I created a new
appTruancy\providers
subfolder, and add it tocomposer.json
- I moved both
Migrator.php
andMigrationServiceProvider.php
into the new folder - I changed the namespace in both of those files to
Truancy\Providers
to match the directory structure - I added
'Truancy\Providers\MigrationsServiceProvider'
to theproviders
array inappTruancy\config\app.php
- I added a
\
in front ofSchema
in themigration
file to reference the base namespace. - I ran dump-autoload to update the classmap
This is one of those cases where I'm not 100% certain that all of the changes were required, but the layout does make sense so I'm happy with it. So, in a nutshell, if you're trying to namespace your migrations, you need to subclass the Migrator class as described in the Medium.com article listed above, but you then need to register the service provider in config\app
, making sure the class names in both files are consistent.
来源:https://stackoverflow.com/questions/29855793/subclassing-migrator-not-working-for-namespaced-migration