Composer: Autoloading Libraries Without Namespaces
The dependency management tool Composer is excellent for easily including third party libraries into your project. It takes care of handling version requirements as per the specified requirements, and handles autoloading of classes as well. Most libraries make use of namespaces by now, which were added to PHP in version 5.3.0. However, you might still encounter libraries that do not use namespaces for various reasons. How does one go about making such libraries available in one’s project with Composer? That is what we will discuss in this article.
Including Libraries
The first thing you have to do is to add such a library to your composer.json file as you normally would. For example, if you wanted to include version 1.0.0 or newer of the imaginary “php-sdk” library, then your composer.json file could look something like the below.
{
"name": "my-vendor/my-project",
"description": "Description of my project",
"require": {
"php": ">=5.3.3",
"codingexplained/php-sdk": ">=1.0.0"
}
}
This will ensure that the php-sdk library is added to your vendor directory, but because the library does not comply with the PSR-0 autoloading standard, it will not be available in your project yet.
Luckily Composer assists us with the files and classmap options for accomplishing this. The former is useful for autoloading single files, which is discussed in the next section of the article. The classmap option lets us specify paths that Composer should recursively scan for *.php and *.inc files. The matching files are then all merged into a key-value array in vendor/composer/autoload_classmap.php. The keys are then looked up in the classmap when a given class or interface is used, and the path to the file is the associated value such that it can be read from the file system. One can also specify file names which will then also be scanned for classes or interfaces.
This all happens automatically because Composer is doing all the work for you, so you do not need to worry about this or to even understand what happens. Below is an example of how we can tell Composer to generate the classmap for us.
{
"name": "my-vendor/my-project",
"description": "Description of my project",
"require": {
"php": ">=5.3.3",
"codingexplained/php-sdk": ">=1.0.0"
}
"autoload": {
"classmap": ["vendor/codingexplained/php-sdk/src/", "vendor/codingexplained/shared/MyClass.php"]
}
}
Provided that our project is correctly set up to use Composer’s autoloading, we should now be able to make use of classes from the library from within the global namespace.
$myClass = new \MyClass();
Next, we will discuss how to include single files.
Including Single Files
If you do not need to use an entire library but merely one or a couple of individual files, then Composer’s files option is quite useful. It may, for instance, be the case that your project needs to use a collection of functions that cannot be autoloaded. We can include such files like shown below.
{
"name": "my-vendor/my-project",
"description": "Description of my project",
"require": {
"php": ">=5.3.3",
"codingexplained/php-sdk": ">=1.0.0"
}
"autoload": {
"classmap": ["vendor/codingexplained/php-sdk/src/", "vendor/codingexplained/shared/MyClass.php"],
"files": ["vendor/codingexplained/shared/functions.php"]
}
}
As you can see, it is indeed possible to combine both approaches at once. One thing to note is that files added to the files option will be loaded on every request. Therefore you should carefully consider how much code you load with this approach as loading unnecessary files will result in a performance overhead. One could argue that this technique is equivalent to adding a series of include or require statements to your project’s bootstrap file. The result is identical, but the solution is more structured with Composer and thus much easier to maintain. This comparison is just to give you an idea of what is actually happening with this approach and why its use should be as limited as possible.
I hope that you found this article useful. Thank you for reading.
2 comments on »Composer: Autoloading Libraries Without Namespaces«
Great, worked just how i needed using the files array.
The only addition i’d make for noobs like me would be that once you’ve edited composer.json you’ll need to go ahead and do a `composer install` to commit everything and generate the composer.lock file and autoloader code
Thanks again Bo, big help :)
Paul
Ah, guess I didn’t think of mentioning that. Thanks for the feedback and I am glad that the post was helpful to you! :-)