Proper Namespacing in Laravel

composer-php, laravel, laravel-4, php, psr-0

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

Problem

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.

Original source