A Beginner’s Guide To Composer

Since its release on March 1st, 2012 Composer has gained widespread popularity for bringing something to PHP which was sorely needed: dependency management. Composer is essentially a way to pull in all the third party software such as CSS frameworks, jQuery plugins and others into your project.

I’m sure there are plenty of coders out there who are wondering about the benefits of using composer and many who are afraid to make the leap into a new system. In this article we’ll take a look at what exactly Composer is, what it does and why it is a great tool for PHP projects.

First we’ll take a broader scope look at dependency management and then install composer. We’ll take a general look at usage and then flesh out some of the basics. Let’s get started!

What Is Dependency Management?

Dependency management is actually a pretty simple concept. Let’s assume you’re creating a one-page website using the Foundation framework for your Javascript and CSS needs. How do you make sure that Foundation is added to your project?

The usual approach is to go to the website, download the package and place it somewhere within your project. So far so good. Now, what do you do when you want to update to the latest version? You repeat the same thing, overwriting the old version.

Let’s assume this goes on for a while and you realize something is broken. They’ve changed something in Foundation and now you have to roll back, but where to? You’ll need to find the older versions and start applying them until you find the right one.

Even if you sort all that out, let’s say you move onto someone else’s project. Are they using Foundation as well? If so, where is it installed and what version is it?

These may not seem like huge issues for a small project but imagine a project with 8-10 dependencies – which still isn’t a lot. Managing everything modularly becomes impossible or – at the very least – a waste of time.

Dependency management solves these problems by automating and standardizing. The retrieval of dependencies such as Foundation, jQuery, Twig, Symphony, logging modules and so on can be done programmatically. Preferred versions can also be designated which protects against conflicts.

A dependency manager standardizes the way the packages are stored and where they are used from. In practice this means that every project that uses the same dependency manager will follow the same structure – at least for dependencies.

Installing Composer

Composer is available on any system you’d like. On Windows you should use the Composer Setup file which can be found on the Getting Started page. On Linux based systems, including OSX, you can use the following command to install it locally:


curl -sS https://getcomposer.org/installer | php

Run the above command from your project directory. This will give you a composer.phar file which you can use in that directory. I prefer to install the command globally so I can use it in any folder I like. To make this happen, issue the following command as well:


mv composer.phar /usr/local/bin/composer

There are two things which could go wrong. If you need admin privileges here you will need to run this command with sudo.


mv composer.phar /usr/local/bin/composer

In Yosemite this command may fail because the usr directory doesn’t exist. In this case, create the directory structure first and then move the file as usual.

An Introduction To Composer

There are two separate elements to dependency management with Composer. The first is Composer itself which is a command line tool for grabbing and managing dependencies. The second is Packagist – the main composer repository. This is where the packages you may want to use are stored.

When using Composer the heart of your dependency management will be a single JSON file named composer.json. The nuts and bolts look something like this:


{
    "name": "danielpataki/my_project",
    "description": "My New Project",
    "authors": [
        {
            "name": "Daniel Pataki",
            "email": "mail@mymail.com"
        }
    ],
    "require": {
        "monolog/monolog": "1.12.0"
    }
}

The requirements of you project will be listed in the require section. In this case I’ve required Monolog, a popular framework for logging things. Just because I have a JSON file with this information doesn’t mean I can start using Monolog. Here’s where the command line comes in.

Using the terminal, in the project folder I issue the composer install command. This will bring all my dependencies into the project and do some other neat things.

composer_install

A vendor directory has been created which should contain all dependencies – including composer itself. The screenshot also shows monolog and psr which is a dependency of monolog in addition to a composer.lock file.

At this point you can start using your dependencies but there is a lot more we can learn and do to be more efficient. Let’s go step-by-step and learn a bit more about Composer.

Specifying Versions

In our code above we wanted to retrieve version 1.12.0 specifically but there may be cases where we want to be a bit more forgiving. There are six ways to specify the version you want, let’s look at them:

Version Range

Using comparison operators you can grab version higher than 1.3, lower than 1.8 or follow an even more complex ruleset by using AND and OR logic. Operators used can be >, <, >=, <= and !=. AND logic is represented by a space or comma, OR logic is represented by double pipes: ||.

Specifying >2.7 would mean any version above 2.7. >2.7 <=3.5 would allow for any version above 2.7 right up until – and including – 3.5.

Wildcard Versions

By using a wildcard you can specify a pattern. 2.3.* would be encompass everything above and including 2.3.0 and below – but not including – 2.4.0. It is equivalent to >=2.3.0 <2.4.

Hyphen Ranges

Hyphen ranges allow you to specify a range more easily, although it is a bit easier to get confused because of how it handles partial versions. A full version consists of three numbers in which case hyphen ranges make perfect sense.

2.0.0 - 3.0.0 is an inclusive range which means that all versions above and including 2.0.0 and below and including 3.0.0 will be accepted.

Partial versions like 2.0 - 3.0 means any version above – and including – 2.0 right up until but not including version 3.1.

The reason for this seemingly weird behaviour is that the left side is inclusive, the right side is completed with a wildcard. The expression above would be equivalent to >=2.1 <3.1.0

Tilde Range

A tilde range is great for targeting a minimum required version and allowing anything up to, but not including, the next major release. If you specify ~3.6 you are allowing 3.6 and everything up to, but not including 4.0.

This method of specifying a version is equivalent to >-3.6 <4.0.

Caret Range

The caret range is meant to allow all non-breaking updates. If a project follows semantic versioning there shouldn’t be any enhancements that break compatibility within a major branch. That is to say any thing above and including a major version and below and not including the next major version should be safe to use. By specifying ^3.3.5 you are allowing anything right up to, but not including, 4.0.

Dev-Master

By specifying dev-master you are grabbing the currently developed latest release which hasn’t been tagged with a version number yet. This can be just fine while developing but you need to be aware that the potential for bugs is higher in these versions.

Locking

Locking of dependencies is one of the most useful features of Composer. I mentioned the composer.lock file eariler. What this does is lock down the versions of the used components.

The lock file can make sure that everyone works with the same versions of files. Just because the application shouldn’t break due to a component update doesn’t mean that all your teammates and your production server should all be running separate versions.

When you first use Composer to grab a dependency it writes the exact version to the lock file. If you specified 2.3.* and 2.3.5 is the latest version the installed version will be 2.3.5 and it will be entered into the lock file.

Let’s say a developer joins the team 10 days later. By this time the dependency has been updated to 2.3.6. If he uses the correct command (composer install) he will receive 2.3.5 because it is locked in place.

You can of course decide to update your dependencies. In this case you should run composer update. This will grab the latest versions allowed and write them to the lock file. This will then be distributed to all sources which can in turn be updated.

Development Requirements

Composer allows you to specify development requirements. This is done by specifying your requirements in the require-dev array instead of the require array.


{
    "name": "danielpataki/my_project",
    "description": "My New Project",
    "authors": [
        {
            "name": "Daniel Pataki",
            "email": "mail@mymail.com"
        }
    ],
    "require": {
        "monolog/monolog": "1.12.0"
    },
    "require-dev" : {
        "fzaninotto/faker", "dev-master"
    }
}

Faker is a PHP class that generates fake data. This is great for development but in production it reallt isn’t required.

Be aware that development requirements are always installed by default, Composer doesn’t magically know when it is being run on your production server. If you want to exclude development requirements you will need to run the install or update command with the --no-dev option.

Composer In The Wild

Composer is used everywhere in the PHP World. All large and well-known website components such as jQuery, Foundation, Bootstrap, even WordPress itself has a composer package available.

In addition, smaller but equally useful code can be retrieved via composer. Logging packages such as monolog, PHP mailers, string manipulation classes, PHP Unit and other tools also around.

The framework community has benefited greatly from Composer’s capability to unify project requirements. The much-adored Laravel, FuelPHP, Yii Framework and others rely on composer for bringing together shared functionality for projects.

The biggest benefit is of course hidden from view. Composer is great when you need to share or deploy code. You don’t need to lug around 20-50Mb of related but unused code. You can just check in the composer.json and lock files and everyone will be on the same page within minutes.

Conclusion

There are many-many more things you can do with Composer but I hope I’ve given you a glimpse into its power. In addition to what we talked about, Composer gives you excellent autoloading out of the box, you can hook scripts into any step of the update processes and so on.

Any group project should use Composer but it’s pretty useful even if you work alone. It gives you a lot of flexibility and it future-proofs your project – you never know when you may need an extra hand with it!

Daniel Pataki

Hallo, my name is Daniel :) I build plugins, themes and apps - then proceed to write or talk about them. When not coding or writing you'll find me playing board games or running with my dog. Drop me a line on Twitter or visit my personal website.