Question

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.

Was it helpful?

Solution

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top