How Composer Autoloads PHP Files
Composer is an application-level dependency manager for PHP. Dependency simply means libraries/packages your application depends upon. Apart from managing the dependencies, composer will also autoload the files needed for the application. Most of the frameworks (Laravel, Symfony, etc) use composer and it’s autoloading by default.
What is autoloading?
Autoloading means the automatic loading of the files required for your project/application. That is including the files required for your application without explicitly including it with include() or require() functions.
Autoloading allows us to use PHP files without the need to require() or include() them and is considered a hallmark of modern-day programming.
Why do we need it?
Including files using include() or require() will be ok if your project contains less no. of files. But most of the real-world applications contain a huge no. of files. So including files using the above-mentioned functions will become a tedious task. It will become even more difficult if our project depends on a lot of external libraries/packages.
So we need an easy way of loading files. Autoloading can help us here.
How It works?
Let’s take a look at a simple autoloader.
class Autoloader public function autoLoad($className) //logic for finding class path include $fullyResolvedPath; > > spl_autoload_register(['Autoloader', 'autoLoad']); $obj = new DemoClass;
Here we used the built-in php function spl_autoload_register() to register our autoload function. What this does is it tells php
«Hey if you can’t find the class yourself, let me find it for you. If I can’t find it, then throw an error.»
Inside the autoloader we provided, we can find the path to the class and then include it using the include() function.
Types of autoloading
Composer supports the following types of autoloading.
Autoloading types and its rule can be defined in the composer.json file. You can configure multiple types of autoloading in a single application. Among these PSR-4 and PSR-0 are the autoloading standards proposed by the PHP-FIG Group.
Classmap
Classmap as its name implies creates a mapping of all the classes inside the specified directories into a single key => value array, which can be found in the generated file vendor/composer/autoload_classmap.php . The automatic file generation happens on composer install/update .
"autoload": "classmap": ["src/", "lib/", "Something.php"] > >
The mapping is done by scanning for all classes inside .php and .inc files in the specified directories. This is the fastest way of autoloading since it uses array lookup for finding the classes.
PSR-0
This is the PSR standard for autoloading files before PSR-4 and it is now Deprecated. You can define the PSR-0 rules in the config file as a mapping from namespace to paths, relative to the package/application root.
"autoload": "psr-0": "Acme\\Foo\\": "src/", "Vendor\\Namespace\\": "src/", "Vendor_Namespace_": "src/" > > >
All PSR-0 references are combined into a single key => value array, which can be found in the generated file vendor/composer/autoload_namespaces.php . During autoloading PSR-0 looks for the namespace in the generated array and resolves the path from its value.
For example, Acme\Foo\Bar would resolve to src/Acme/Foo/Bar.php . PSR-0 also supports underscores( _ ) in class names. Each _ character in the class name is converted to a DIRECTORY_SEPARATOR . So that Acme_Foo_Bar would also be resolved to src/Acme/Foo/Bar.php .
PSR-4
PSR-4 is currently the recommended way of autoloading since it offers greater ease of use.
"autoload": "psr-4": "Acme\\Foo\\": "src/", "Vendor\\Namespace\\": "" > > >
Unlike PSR-0 underscores will not be converted to DIRECTORY_SEPARATOR and the namespace prefix is not present in the path.
For example, Acme\Foo\Bar would resolve to src/Bar.php .
All the PSR-4 references are combined, during install/update into a single key => value array, which can be found at vendor/composer/autoload_psr4.php .
Files
Classmap, PSR-0, and PSR-4 deal with classes only. If you want to autoload functions, you can use files autoloading. This can be useful to load your helper functions. These files will be loaded on every request.
"autoload": "files": ["src/helpers.php"] > >
Note on Classmap and PSR-4
Classmap autoloading is the fastest among autoloaders since it loads classes from the prebuilt array. But the problem with classmap is that you need to regenerate the classmap array every time you create a new class file. So in the development environment PSR-4 autoloading will be the most suited one.
PSR-4 autoloading will be slower compared to classmap because, it needs to check the filesystem before resolving a classname conclusively. But in production you want things to be as fast as possible.
For this reason, composer offers classmap generation from PSR-4. Classmap generation converts all PSR-4/PSR-0 rules into classmap rules. So autoloading will be faster. If a PSR-4 class is not found in the generated classmap, the autoloading fallback to PSR-4 rules.
Classmap generation can be enabled in any of the following ways.
- Set «optimize-autoloader»: true inside the config key of composer.json
- Call install or update with -o / —optimize-autoloader
- Call dump-autoload with -o / —optimize
Putting it all together
Now we can look into how composer autoloads our files combining all these autoloaders. First of all, we need to include composer’s autoload.php file.
require __DIR__.'/../vendor/autoload.php';
It requires another file composer/autoload_real.php and calls the getLoader() method on the generated composer autoloader class.
require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInitcac18dc222d8ea1e03bdef8b44290883::getLoader();
In the getLoader() method, composer loads all autoloader arrays which are generated on composer install/update or on composer dump-autoload and it also registers the autoload function using the spl_autoload_register() which is mentioned earlier.
// autoload_real.php public static function getLoader() // . self::$loader = $loader = new \Composer\Autoload\ClassLoader(); // Loads all autoloader arrays $loader->register(true); // . return $loader; >
The register() method in ClassLoader class register the autoload function loadClass() .
class ClassLoader public function register($prepend = false) spl_autoload_register(array($this, 'loadClass'), true, $prepend); > >
The loadClass() method is simple. It calls another method findFile() with the class name and if the method returns a valid file path, then it class another helper function includeFile() with the file path, which simply includes the file at the given file path.
public function loadClass($class) if ($file = $this->findFile($class)) includeFile($file); return true; > >
The findFile() method is responsible for finding the file path. Since its implementation is a little bit complex, we won’t discuss it here. But all you need to know is that it checks for file path lookup in the following way.
- Check if classmap contains the specified class if found return immediately with the file path.
- If the file is not found in classmap, psr-4 lookup is made, if found return with the generated file path.
- If the psr-4 lookup is not successful, psr-0 lookup is made, if found return with the generated file path.
That’s it. Composer does a good job of autoloading your files and provides you with a variety of options to configure them and make development a breeze.
How to Autoload Classes With Composer in PHP
Sajal Soni Last updated Aug 19, 2020
In this article, we’ll discuss the basics of autoloading in PHP and how to autoload PHP classes with Composer. I’ll explain why autoloading is so important and show you how to use Composer for autoloading step by step. I’ll also explain the difference between the different kinds of autoloading in Composer.
Why Do We Need Autoloading?
When you build PHP applications, you may need to use third-party libraries. And as you know, if you want to use these libraries in your application, you need to include them in your source files by using require or include statements.
These require or include statements are fine as long as you’re developing small applications. But as your application grows, the list of require or include statements gets longer and longer, which is a bit annoying and difficult to maintain. The other problem with this approach is that you’re loading the entire libraries in your application, including the parts you’re not even using. This leads to a heavier memory footprint for your application.
To overcome this problem, it would be ideal to load classes only when they are actually needed. That’s where autoloading comes in. Basically, when you use a class in your application, the autoloader checks if it’s already loaded, and if not, the autoloader loads the necessary class into memory. So the class is loaded on the fly where it’s needed—this is called autoloading. When you’re using autoloading, you don’t need to include all the library files manually; you just need to include the autoloader file which contains the logic of autoloading, and the necessary classes will be included dynamically.
Later in this article, we’ll look at autoloading with Composer. But first, I’ll explain how you can implement autoloading in PHP without Composer.
How Autoloading Works Without Composer
You might not realize it, but it is possible to implement autoloading in PHP without Composer. The spl_autoload_register() function is what makes this possible. The spl_autoload_register() function allows you to register functions that will be put into a queue to be triggered sequentially when PHP tries to load classes that are not loaded yet.
Let’s quickly go through the following example to understand how it works.
function custom_autoloader($class)