Optimize composer’s autoloader

Most people write really simple autoloaders for their PHP projects that look at a class or namespace prefix, perform a file_exists and finally require_once the file. Something like:

//Register an autoloader for our plugin's actual code
spl_autoload_register(
                        function ( $class )
                        {
                            //PSR-4 compliant autoloader
                            //See http://www.php-fig.org/psr/psr-4/
                            $prefixes = array(
                                                'My\\Namespace\\' => __DIR__. '/src/My/Namespace/',
                                            );

                            foreach( $prefixes as $prefix => $base_dir )
                            {
                                // does the class use the namespace prefix?
                                $len = strlen( $prefix );
                                if ( 0 !== strncmp( $prefix, $class, $len ) )
                                {
                                    // no, move to the next registered prefix
                                    continue;
                                }

                                // get the relative class name
                                $relative_class = substr( $class, $len );

                                // replace the namespace prefix with the base directory, replace namespace
                                // separators with directory separators in the relative class name, append
                                // with .php
                                $file = $base_dir . str_replace( '\\', '/', $relative_class ) . '.php';

                                // if the file exists, require it
                                if ( file_exists( $file ) )
                                {
                                    require_once $file;
                                }
                            }
                        }
                    );

This is also pretty much what composer does, too, when you require a package. Unfortunately once you get a bunch of packages (and let’s be honest, that’s happening more and more often these days) that file_exists code starts to get really expensive, especially when packages share the same namespace because each package needs to be scanned for that file.

But luckily has a fix for this! You can tell composer to scan all of your currently installed packages and make a giant array. One framework developer reported a 37% boost in performance by doing this!

composer dump-autoload --optimize

If you have a giant install this might take a while (not sure how much, though).

Each time you use composer to add/remove/update packages you need to re-run this command, however, if you want to retain these optimizations. (Actually, you might completely lose these optimizations, I’m not sure and haven’t tested yet.) The good news once again is that you can specify this in your composer.json file:

    "config": {
        "optimize-autoloader": true
    }

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.