I'm trying to namespace my Models in Laravel, and also have them be autoloaded automagically like the normal models do in the root of app/models. composer dump-autoload
works, but I don't want to run that after I create a new model.
#app/models/MyNamespace/Thing.php
<?php
namespace App\Models\MyNamespace;
class Thing {
// ...
}
#app/routes.php
<?php
Route::get('test', function(){
$thing = new App\Models\MyNamespace\Thing;
});
If I run composer dump-autoload
everything is fine, otherwise I get a class not found exception.
What can I do to make that kind of structure work without rebuilding the classmap every time I make a new class? I think PSR-0 is where your namespaces correlate directly with your directory structure, and it appears as though my classes are adhering to that...
I've also tried using the Workbench which works great, but ideally I'd like to have, for ex: app/models/MyNamespace, app/models/AnotherNamespace.
This is not a Laravel 'problem', this is something that will work, exactly the same way, on every application that uses Composer.
If your classes are following the psr-0 rules (directory structure matters!), you can configure it in your composer.json
{
"autoload": {
"psr-0": {"MyNamespace\\": "app/models"}
}
}
Execute
composer dump-autoload
Once and it it will show in your autoload_namespaces.php. After that Composer will be able to find your classes by its namespaces, no need to dump-autoload
again.
To explain better how it works. If you do
"psr-0": {"MyNamespace\\": "app/models"}
You must use it this way:
$user = new MyNamespace\User.php
Because Composer adds your namespace to the end of your namespace path and it will expect to find User.php in
/var/www/yourappdir/app/models/MyNamespace/User.php
So, by doing
"psr-0": { "App\\Models\\": "" }
You are telling Composer that ALL /var/www/yourappdir/App/Models
subfolders can contain namespaced files of the App\Models namespace. And you'll be able to address files like:
$user = new App\Models\User.php
$user = new App\Models\MyNamespace\User.php
$user = new App\Models\MyNamespace\Foo\Bar\User.php
And if you do
"psr-0": { "App\\Foo": "" }
Composer will be able to address those namespaces
/var/www/yourappdir/App/Foo
/var/www/yourappdir/App/FooBar
/var/www/yourappdir/App/Foo/Bar
/var/www/yourappdir/App/Foo/Bar/Baz
But if you do
"psr-0": { "App\\Foo\\": "" }
It will be able to address just
/var/www/yourappdir/App/Foo
/var/www/yourappdir/App/Foo/Bar
/var/www/yourappdir/App/Foo/Bar/Baz