Categories


Archives


Recent Posts


Categories


Laravel’s Framework Autoloader

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

Last time we said we’d be wrapping up our series on the Laravel 4.2 autoloader. Apparently we were fibbing, because I just realized we’ve failed to cover a key concept in Laravel autoloading, and one that would be impossible to shoe horn into an existing article. So this time it’s another quick tutorial before we dive back in.

Application vs. Framework

So far in this series, when it comes to Composer, we’ve focused almost exclusively on the Laravel application autoloaders. That is, any Laravel project is split into two sections — there’s the application code that you’ll edit and add to on a regular basis (everything not in vendor/), but then there’s the Laravel framework code (which lives in vendor/laravel/framework).

When you create a new Laravel project, Laravel generates a composer.json file for you, with an autoloader section that looks something like this

#File: composer.json
"autoload": {
    "classmap": [
        "app/commands",
        "app/controllers",
        "app/models",
        "app/database/migrations",
        "app/database/seeds",
        "app/tests/TestCase.php"
    ]
},

If you’ve been following along, you know this section means anytime you update your Composer project (or manually run composer dumpautoload), Composer will traverse each of the directories above and generate a classmap, and the registered Composer autoloader will use this classmap to load a class’s definition.

However, this isn’t the only autoloader related code in your project — we’ve touched on this a bit with the SwiftMailer autoloader, but somehow failed to mention that the laravel/framework package has its own autoloader section.

Laravel’s Framework Autoloader

If you take a look at the Laravel Framework’s composer.json, you’ll see it also has an autoloader section.

#File: vendor/laravel/framework/composer.json
"autoload": {
    "classmap": [
        "src/Illuminate/Queue/IlluminateQueueClosure.php"
    ],
    "files": [
        "src/Illuminate/Support/helpers.php"
    ],
    "psr-0": {
        "Illuminate": "src/"
    }
},

Here we see an example of nearly every type of Composer autoloader, save psr-4. Working our way from the bottom up, the following section

#File: vendor/laravel/framework/composer.json 
"psr-0": {
    "Illuminate": "src/"
}

is the main autoloader for the framework. It’s the psr-0 autoloader that tells Composer to look for Illuminate prefixed classes in the

vendor/laravel/framework/src

folder. If you need a refresher on what this means, we covered the details of psr-0 in a two part Composer Autoloader Features article.

Moving up the list, we have this section

#File: vendor/laravel/framework/composer.json
"files": [
    "src/Illuminate/Support/helpers.php"
],

This is the files autoloader. As previously covered, all this section does is ensure that, during Composers autoloader bootstrapping, it includes in the file at

vendor/laravel/framework/src/Illuminate/Support/helpers.php

This file has nothing to do with class autoloading, and instead defines a number of global PHP helper functions.

Finally, we have a single file specified for classmap autoloading

#File: vendor/laravel/framework/composer.json    
"classmap": [
    "src/Illuminate/Queue/IlluminateQueueClosure.php"
],

This one’s a curious historical artifact. The class definition is a little odd

#File: vendor/laravel/framework/src/Illuminate/Queue/IlluminateQueueClosure.php

use Illuminate\Encryption\Encrypter;

class IlluminateQueueClosure {

}

That is, despite being located in a directory that would imply its full name is Illuminate\Queue\IlluminateQueueClosure — in actuality the file defines a global class (IlluminateQueueClosure) class. i.e. — a class in the global namespace. So, that explains why this class needs a classmap autoloader — it’s not psr-0 compliant — but what it doesn’t explain is why this needs to be a global class. My guess is there’s something about the queue job runner that assumes/prefers a global class vs. one with a namespace.

Wrap Up

That’s it for today. Next time we’ll do a much deeper dive on how Laravel’s different autoloaders interact with each other, and some edge cases that can seem like heisenbugs unless you’re familiar with the specifics of Laravel’s autoloader architecture.

Originally published February 11, 2015
Series Navigation<< Registering Laravel’s AutoloadersLaravel Autoloader Interactions >>

Copyright © Alan Storm 1975 – 2017 All Rights Reserved

Originally Posted: 11th February 2015