We’ve been taking a closer look at using Composer to manage dependencies in our PHP projects. Getting up to speed with composer takes some practice and diligence just like any other part of programming. There is a bit of a learning curve, and while you can do all the things Composer offers manually, if you take the time to learn the tool, your workflow will be more streamlined and efficient. It’s a lot like Laravel actually. Laravel teaches you to use better coding practices, and if you are new to them, your programming speed will probably actually decline at first. Much like using Composer however, if you put in the time up front to learn more efficient ways of doing things, it will benefit you greatly in the longer run. In this episode we’ll take a closer look at Autoloading using Composer.
Four Ways to Autoload
With composer, you specify in your composer.json
file how and what you will autoload for a given project. There is an autoload object within the composer.json
which you can populate with one or more of these four techniques to make use of autoloading. You have the option of File Based Autoloading, Classmap Based Autoloading, PSR-0 Autoloading, and PSR-4 Autoloading. These would be referenced by the keys files
classmap
psr-0
and psr-4
. At the time of this writing, the official documentation for Composer is recommending PSR-4, but we’ll take a look at all four options.
1. File Based Autoloading
First up we’ll do a simple example of File Based Autoloading using Composer.
- In our web root, create a folder named
aldemo
, for auto load demo. - Now we can add a folder to hold our custom code. We can call it
mylibrary
- Add a
functions.php
file in there, and define a custom function for yourself. We’ll use this one, but you can create your own if you like.<?php function lego () { return 'You are now a master builder.'; }
- Now we can use Composer to generate the autoload files for us. Create a
composer.json
file and place it in thealdemo
folder like so:{ "autoload": { "files": ["mylibrary/functions.php"] } }
- Run
composer dump
in thealdemo
folder. It will note that it is Generating autoload files for you. - Create an
index.php
file in thealdemo
folder and make a call to your new function. We simply did this:<?php echo lego();
- Now load up your page in the browser
http://localhost/aldemo/
and see the result. Ouch. That didn’t work out so well: Fatal error: Call to undefined function lego() in C:wampwwwaldemoindex.php on line 3 - We still need to include the autoloader like so! require
'vendor/autoload.php';
. Yourindex.php
will now look like:<?php require 'vendor/autoload.php'; echo lego();
- Once again go ahead and visit
http://localhost/aldemo/
and observe that yes, You are now a master builder.
2. Classmap Based Autoloading
Now we can take a look at how to do Classmap Based Autoloading. This one is better than files since you don’t have to specify the actual file itself, just the directory it lives in. We used this approach in our Custom Helper Functions in Laravel Episode.
- Create a folder called
classmap
in thealdemo
folder. - Add a
functions.php
file that contains some simple logic, we’ll use this:<?php Class Cmautoload { public function classmap () { return 'that knows how to autoload with a classmap! '; } }
Note that you need to use a Class! The
classmap
loads only Classes, whereas withfiles
, you can load native functions. - Update your
index.php
to include a call to the new function:<?php require 'vendor/autoload.php'; echo lego(); $cm = new Cmautoload; echo $cm->classmap();
- Update your
composer.json
like so:{ "autoload": { "files": ["mylibrary/functions.php"], "classmap": [ "classmap" ] } }
The naming might not have been the best for this example, but it will do. You’ll see the new classmap object within the autoload object, and it now has an array with one value, classmap. That says, “We are using a classmap, and I want you to look in the classmap folder to autoload any classes you find.”
- Run
composer dump
in thealdemo
folder - Load
http://localhost/aldemo/
and you’ll see that You are now a master builder, that knows how to autoload with a classmap!
3. PSR-0 Based Autoloading
At this point we’ll get just slightly more advanced and make use of PSR-0 autoloading. I’m not one for crazy verbiage so if you want every single detail, read the spec. For me, PSR-0 just means we’re using namespaces in this convention <Vendor Name>(<Namespace>)*<Class Name>
. The main point is the namespaces need to follow the folder structure.
- Ok we know that
aldemo
is our root folder, so lets add the following folders into this directory/src/vegibit/library
. - Now, we can create a
greeting.php
class file in the/src/vegibit/library
folder. It will hold two namesspaces like so:<?php namespace VegibitLibrary; Class Greeting { public function hi() { return "We got you covered"; } } namespace VegithemesLibrary; Class Greeting { public function hi() { return " with Free Twitter Bootstrap Themes!"; } }
Now hold on just a minute! You have two different namespaces in the same
greeting.php
class file. Not only that, each namespace has the exact same class name and method name! Normally PHP would unleash a rath of fury and anger upon you if you tried to do this without namespaces! This is the benefit of namespaces however, you can have classes and methods that use the same name, as long as they are in their own namespace. Excellent! - Let’s update our
composer.json
so that it has the needed info to load these classes using PSR-0{ "autoload": { "files": ["mylibrary/functions.php"], "classmap": [ "classmap" ], "psr-0": { "Vegibit\Library": "src", "Vegithemes\Library": "src" } } }
Now check it out. What this configuration says is, “The VegibitLibrary and VegithemesLibrary namespaces both live in the
src
directory. - Run
composer dump
to update our autoload files. - Now that all of our plumbing is in place, we can use our new code in the
index.php
file. Let’s update it like so:<?php require 'vendor/autoload.php'; echo lego(); $cm = new Cmautoload; echo $cm->classmap(); $vb = new VegibitLibraryGreeting; $vt = new VegithemesLibraryGreeting; echo $vb->hi(); echo $vt->hi();
- Finally, we can visit
http://localhost/aldemo/
and find that You are now a master builder, that knows how to autoload with a classmap! We got you covered with Free Twitter Bootstrap Themes! Awesome!
4. PSR-4 Based Autoloading
PSR-0 has been the cutting edge method of using autoloading in PHP… until now. The new kid on the block is PSR-4 autoloading. At the time of this writing, PSR-4 is the recommended method of autoloading according to the official Composer Documentation. So what’s the big deal with this PSR-4 business? Let’s examine.
With PSR-0, we needed to map our namespaces exactly to our directory structure. This turns out to create a lot of empty folders in the file system, which might not be the best way to do things. In some respects, I think it actually helps to keep the consistency. On the other hand, why create such a verbose directory structure if you don’t have to? Well, in PSR-0, you have to. In PSR-4 however, you can shorten your directory structure while still using the same lengthy namespacing.
- Let’s remove our
greeting.php
class file fromaldemo/src/vegibit/library
and place it in thealdemo/src
directory. - Delete the
vegibit/library
directories. We are now left withaldemo/src/greeting.php
. - Now, at this point, we have the same
greeting.php
class file, and it uses the same namespacing within the file, and our code in theindex.php
file is trying to use these classes in the same way. The only difference is that we moved the physical location of the file fromaldemo/src/vegibit/library
toaldemo/src
. In ourcomposer.json
, we already said that ourVegibit/Library
andVegithemes/Library
namespaces live in thesrc
directory, so in theory this should all still work right? Let’s try: - Load up
http://localhost/aldemo/
and whoops, Fatal error: Class ‘VegibitLibraryGreeting’ not found in C:wampwwwaldemoindex.php on line 10. Ok, it’s not working. Well, what we just did was basically break the rules of PSR-0, which is that the directory structure must follow the namespaces. - Let’s make just a small tweak to our
composer.json
file. It now looks like this:{ "autoload": { "files": ["mylibrary/functions.php"], "classmap": [ "classmap" ], "psr-4": { "Vegibit\Library\": "src", "Vegithemes\Library\": "src" } } }
We changed psr-0 to psr-4, and added \ to the end of our namespaces which is a requirement of psr-4.
- Run
composer dump
- Visit
http://localhost/aldemo/
one more time and find that, yes, You are now a master builder, that knows how to autoload with a classmap! We got you covered with Free Twitter Bootstrap Themes! It works!
So you see, using PSR-0, developers were forced to use lengthy directory structures which created a lot of empty directories. This was only needed to make the autoloader work. With PSR-4, we no longer have to use such verbose directory paths.
Composer Autoloading Conclusion
We covered a lot of ground here! We had a good look at the four methods of using autoloading in Composer. We can use files, classmaps, psr-0, and psr-4. It is most definitely worth the time to learn Composer and make use of all the benefits it can provide you with!
Thank you for reading Composer Autoloading Tutorial – Please do share using the buttons below!