PHP Best Practices and Tips
Manage Your Dependencies in PHP with Composer
What Is a Dependency?
PHP is a great language to create web projects. One of the things you will see when using PHP is that there is a library for almost anything you need.
A dependency in your project is a library or package that your code uses for performing tasks. For example, if you need to call a REST API you can use the curl library of PHP, or better yet, use the Guzzle library, that have all the things you need for creating the calls.
The Problem with Dependency Management
One common problem of using third party code is keeping it updated while time goes on. Also, there are libraries that depend on other libraries, that depends on other libraries, and so on. That is really a bad situation in a dynamic context as web development is. Not to mention which version of the library you’ll use, as sometimes you need a different version according to the context you’re in, for example, the PHP version your server has.
And there is another catch. Requiring libraries is a big pain, you have to write all the includes into the file that needs to use a given library. When removing that class, you have to clean all the includes and delete the library. And as we all know, that can almost never happen, and we end up with a big folder of deprecated libraries, and then we need to waste our time (or the time of your team) to clean all that mess.
Meet Composer, Your New Friend
Composer is here to solve all those problems for us. When I first started using Composer, I thought it was a package manager, like Yum or Apt. However as they state in their documentation, they are a dependency management and not a package manager, because the packages are not installed globally. Instead, the packages are installed under a vendor folder inside your project.
How to Manage Dependencies
I won’t go over every detail. You can find a step by step guide explained in their getting started page, but I’ll explain quickly what you need.
First you need to install Composer. I recommend to install it globally, and set it up so you have the Composer command available. Once you do that you have to create a composer.json
file in the root of your project.
If you want to add a new library to your project, all you have to do is add it to that file with the version you need, which looks something like this:
{
"require": {
"vendor/package": "1.3.2",
"vendor/package2": "1.*",
"vendor/package3": "^2.0.3"
}
}
Once you do that, next you have to run in the command line composer install
and Composer will install all the needed libraries inside the vendor/
folder of your project. If you run composer update
, Composer will check for new versions of the libraries and update them accordingly.
Also, Composer will install the dependencies of these libraries without any needed extra work from you.
There are a lot of commands you can use with Composer, run composer --help
to list them all.
Autoload Classes
If you are already falling in love with Composer for this, you’ll definitely love it for what comes next.
Composer offers an autoload for your classes. All you have to do is add this line in top of your project require __DIR__ . '/vendor/autoload.php';
and then just call the constructor of your class. For example, if you’re using Guzzle, you just have to call:
$client = new GuzzleHttp\Client();
and it will work. If you don’t need it anymore, just delete the class and that’s it! Well, I lied, that’s not all but almost. Head to the next section to learn the final step.
Deleting Libraries
We talk about the pain that is deleting a library, because you not only have to be aware of that library but also of the dependencies of that library, and being careful enough not to delete a dependency being use by another library.
In composer this is just as simple as deleting the dependency from the composer.json
file, and run composer update
. Yes, it is that simple.
Meet Packagist, the Repository for Your Projects
As if you already don’t have enough with all this, there is a common repository for finding libraries for your projects that can be used easily with Composer.
Packagist is the place you go when you need a library. There you can search for libraries, and see what version you want to use, depending on your needs. Also, you can write your own packages, and include them there for others to use.
Of course, there are other ways to include packages, like directly from Github or other sources. That is out of the scope of this article, but you can find how to do this in the documentation page of Composer.
Versioning
When you go to the library website, you can see several available versions. In general, you will have one that is ready for production and one that is in development.
How the versioning numbers work? Well, they follow the semantic versioning standard, which is basically as follows:
You have 3 numbers, separated by a dot. So for example, in your composer.json
file you can add something like "guzzlehttp/guzzle": "5.3.*"
for requiring the Guzzle library. The first number, in this case 5, is called the major version. This number changes when big changes are made in the library. Changing this version will probably change the name of the functions, or the classes, or anything. The second number is the minor version, that is meant to be for functionality changes or additions, but having backwards compatibility with other versions. The third number is the patch number. This number is changed each time a bug is fixed, and doesn’t change the functionality of the package.
As you can notice, you can include the wildcard *
for replacing that number. This means that when you run composer update
, Composer will check for the latest number in that category (major, minor or patch) and update to the newer version. It is recommended to keep the last number with a wildcard only, and update the minor version according. However, if you really trust that library and you always want the latest version, you can of course make this a wildcard as well.
You can also use comparator operators to include a range. For example: "guzzlehttp/guzzle": ">=5.3,<5.4"
is equivalent to "guzzlehttp/guzzle": "5.3.*"
, and also is equivalent to "guzzlehttp/guzzle": "~5.3"
using the tilde (~
) operator.
For more about versioning, go to the documentation of Composer about versioning.
Save Disk Space
As a last tip, if you use Git add the vendor folder in your ignore file. Having the Composer file is enough, because once the user downloads the project, it will just have to run a composer install
command to fetch all the libraries.
Summary
In this article we explained what dependencies are, why they are important for our projects, and the problems we have when we deal with them.
After that, we explained how Composer address all those issues in a really smart way to keep your project dependencies organized.
Composer is another tool for your toolbelt that will save you a lot of time and headaches.
Tips are from Toptal Developers