Composer Autoloader: The Easiest Autoloading in PHP

Often, we find ourselves developing on a PHP system that does not have an autoloading mechanism built-in (cough *WordPress*). In times like these we largely just want to set up the world’s simplest autoloading for our project (plugin or theme). This way, we can move on to the fun stuff.

If you’re unfamiliar with the concept of autoloading, we have another post that describes the What, Why, and How of Namespaces and autoloading in PHP.

Autoloader Requirements

Like any other architectural decision, let’s take a moment to define some requirements for our autoloader.

  1. Simple – Any autoloader we use should be dead-simple to set up. After it’s set up, we never want to think or worry about it again. We don’t want to have to write any custom code for our autoloader, we want someone else to do it for us.
  2. Reliable – Our autoloader is not a part of the system we want to be responsible for maintaining, the autoloader should be a utility that we can rely on. Once it’s set up, we never have to think about it again. It works the same way anywhere and everywhere.

Great. That shouldn’t be too hard. And now that I’ve padded this post out enough, let’s get to the answer.

Answer: composer init

Yep. We’re going to run composer init in the directory where we want to generate the autoloader and hit `enter` until it stops asking us questions. Let’s see what that looks like:

Requirement: composer.

$ composer init                                                                                                   ─
  Welcome to the Composer config generator  
This command will guide you through creating your composer.json config.
Package name (<vendor>/<name>) [daggerhart/autoloading-easiest]: 
Description []: 
Author [Jonathan Daggerhart <jonathan@daggerhartlab.com>, n to skip]: 
Minimum Stability []: 
Package Type (e.g. library, project, metapackage, composer-plugin) []: 
License []: 
Define your dependencies.
Would you like to define your dependencies (require) interactively [yes]? 
Search for a package: 
Would you like to define your dev dependencies (require-dev) interactively [yes]? 
Search for a package: 
Add PSR-4 autoload mapping? Maps namespace "Daggerhart\AutoloadingEasiest" to the entered relative path. [src/, n to skip]: 
{
    "name": "daggerhart/autoloading-easiest",
    "autoload": {
        "psr-4": {
            "Daggerhart\\AutoloadingEasiest\\": "src/"
        }
    },
    "authors": [
        {
            "name": "Jonathan Daggerhart",
            "email": "jonathan@daggerhartlab.com"
        }
    ],
    "require": {}
}
Do you confirm generation [yes]? 
Generating autoload files
Generated autoload files
PSR-4 autoloading configured. Use "namespace Daggerhart\AutoloadingEasiest;" in src/
Include the Composer autoloader with: require 'vendor/autoload.php';
composer init

Take a look at line 19. During the composer init process we were asked if we’d like to generate a PSR-4 autoloader based on the package name. This is the result of our secret technique to “hit `enter` until it stops asking us questions”, composer has done everything we wanted.

Composer Autoloader Results

Let’s explore the results a little bit. I’ve created an example repo for this blog post on GitHub.

Note:

  1. We have generated a composer.json file.
  2. The composer.json contains a PSR-4 autoloader statement that targets the src/ folder.
  3. We’ve generated a vendor/ folder that contains our autoloader.

And we got all of that by simply running one command.

Example using the composer autoloading

As a part of this repo, I’ve written a very simple example that shows off the autoloader.

<?php
require_once __DIR__ . '/vendor/autoload.php';
$blog_post = new \Daggerhart\AutoloadingEasiest\Model\BlogPost(
  'My Title',
  'What great content!'
);
$renderer = new \Daggerhart\AutoloadingEasiest\Service\BlogPostRenderer();
echo $renderer->render($blog_post);

In this example, we require the composer generated autoloader, then immediately start using it to automatically load deeply nested classes in the project.

Changing the composer generated autoloader

In the real world, we may want to control the namespaces in our project more carefully. Rather than going with the generated namespace (in this example, Daggerhart\AutoloadingEasiest\), we probably want to use something shorter and more project-specific.

After generating our autoloader it’s fairly easy to change the namespace (or add more namespaces). We just need to do two things:

  1. First, edit the autoload.psr-4 section of our composer.json file to reflect our desired namespace(s).
  2. Then, run composer dump-autoload

“Dumping” the autoloader with composer means “regenerate the autoloader according to composer.json“. After running that command, our autoloader our been updated and we can now use the new preferred namespace.

And that’s it! Hope this helps anyone who finds themselves tired of writing their own autoloader or wondering how to write an autoloader for the very first time.

Check out these other articles on using composer:

0 Thoughts

Discussion

Leave a Reply

Your email address will not be published.