5 Minutes Introduction to Composer

How to make get more stuff done

Nico Anastasio
CodeX
9 min readJul 17, 2020

--

Photo by Leone Venter on Unsplash

If you have ever used PHP, the chance is that you came across the word Composer.

Composer is a tool that let PHP developers around the world declare libraries that their projects need and manage them for you.

This is hands down one of the top 3 tools you MUST LEARN if you want to become a PHP developer professionally.

In this article, we’ll go through the basics of what it is and how to use it.

Let’s start!

One of the first things that the guys that developed Composer took care of was to specify that it is not a package manager

Even though this tool deals with packages (or libraries), it manages them depending on the project they are used to.

You can see Composer more as a dependency manager.

Composer installs them in a directory inside your project and these packages will work on that project only.

(it also supports global projects but it is a topic for another day).

Requirements and installation

Being a dependency manager for PHP means that you will need to have PHP in your system.

Mind-blowing I know.

The minimum specific version of PHP required for it to work is version 5.3.2.

I really hope that nobody that is reading it still runs a version of PHP below 7.

If so please stop reading now and go update your PHP.

You back? Cool

Let’s have a look at how to install Composer on your machine.

Composer is multi-platform, the developers seek to make it work for every SO possible

At the moment, in fact, you can install it on Windows, Linux, and macOS.

Installing Composer on Linux, Unix, or macOS

Composer has an installer that you can use from the command line.

If you are using a Unix-like system it probably means that you are comfortable working with it.

There are two ways to install this tool,

  • Locally within your project
  • Globally as an executable living inside the whole system

To install Composer locally you have to run the installer from within your directory, check the download page out.

What will happen behind the scene is that the installer will check some PHP settings and download the file called composer.phar into your directory.

The format of this file is a PHP archive,

To run Composer you just have to run PHP composer.phar.

You can also use the command below and specify the directory with the flag — install-bin

Here is an example:

php composer-setup.php --install-dir=bin --filename=composer

If you want to install Composer globally instead you have to put the phar file in a directory that is part of your PATH.

After you run the installer you can move the file to the local/bin directory.

Here is the command to use:

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

After you did that you can simply run composer instead of using the command php composer.phar

Windows

Installing Composer on a window machine is even simpler,

What you need to do is just download and execute the composer-setup file.

The executable will update the PATH itself so you are good to go just by running composer on your terminal.

Basic usage

In order to use Composer in your project what you have to do is to have a JSON file.

This file will detail all the dependencies required and it also contains other useful metadata.

The most important thing that you need in your composer.json is the required key.

In the official documentation, they use the monolog package.

What it does is send logs to files, sockets, inboxes, databases, and various web services.

The required key takes an object (that is indicated by its name) and the version.

{    "require": {        "monolog/monolog": "1.0.*"    }}

What Composer does is to check the correct files that match not only the name of the package but the version as well.

The package name is composed of two parts, the name of the vendor and the name of the project, in the case of monolog above the two are identical.

The reason we need both is that two vendors may call their package in the same way, and having the name of the vendor specified avoid clashing errors.

Easy right?

Regarding the value of the version, the specification is a little bit more complex.

In the example above what is required is any version (note the * wildcard) of the monolog package that is greater than or equal to 1.0 and less than 1.1.

You can also specify tags, branches, and the minimum stability required, the guys at Composer actually created an entire blog post about versions and constraints that you can read.

Once you have specified the package required in your project inside the JSON file you can just run the composer install command and the files will magically appear within a vendor folder in the directory of your project.

In the example, you will have a folder vendor/monolog/monolog/ and if monolog had dependencies on its own they will be listed inside the vendor folder too.

Once the installation has finished a composer.lock file that contains all the dependency and their version of the project will be created.

It is a good practice to commit composer.lock to your project’s repo so other PHP developers that are working on the project are locked and have to use the same version.

This is very important!

The reason is that if you update the JSON file with new versions while the project already has a composer.log and then you run the composer install command the versions of the packages between the two files will diverge.

This is by design, you and your collaborators want to maintain a similar version of all the packages, not being able to update the version to ensure that your project does not break because of a change in one or more of your dependencies.

How can you update your dependencies?

You understood that having the composer.lock file in your repository blocks any new version of your dependencies from being updated.

A solution if you actually want to update them is to delete the lock file and run the composer install command again.

This works but as you can imagine is not the best way to deal with this problem.

A much better way to do so is by using the command composer update.

This will fetch the latest matching versions of the dependencies required in your composer.json file and update the lock file with the new versions.

If you want you can also update a single dependency by specifying the one,

Need an example?

This will work:

composer update monolog/monolog

Packagist & Autoloading

There are a few Composer repositories online, these are package sources and can be described as a website where you can get packages from.

The most popular and the one that I’ll advise you to use is Packagist.

If you have an open-source project using Composer it is highly suggested to publish your package on Packagist.

Even though this is not required or mandatory having a library published there will increase the possibility of being discovered, and thus adopted by other developers.

A not common but very interesting thing about Composer is that it has platform packages.

Those are virtual packages for features that are installed on the system but cannot be installed by Composer.

To get the full list of these packages you have to type the following command after having installed Composer

composer show --platform

Lastly,

Now that you have Composer installed and you have required your favorite components you might as well want to use them in your project.

To do that a common practice is to leverage the vendor/autoload.php file.

Composer generates this file automatically and what we can do is just include this file and use the class that has been required.

Here is a snippet with an autoload implementation

require __DIR__ . '/vendor/autoload.php';$log = new Monolog\Logger('name');$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));$log->addWarning('Foo');

It is also possible to add our own code to the autoloader.

We can do so by updating the autoload section of the composer.json.

{
"autoload": {
"psr-4": {"Acme\Foo": "src/Foo.php"}
}
}

As you can see it will register a PSR-4 autoloader

Also, it needs an object with a key and a value, the key will be the namespace of the class whereas the value would be the filename.

After you have updated that, you need to re-generate the autoload file

We are going to do that with the command

composer dump-autoload

or

composer dumpautoload

Worth noticing that Composer supports PSR-0 as well, class-map, and file autoloading. See the autoload reference for more information.

Head over to the autoload page to learn more about it.

Libraries

Something you should understand is that Composer considers every project that has a composer.json file as a package.

If your application has a composer.json package,

If you are requiring some package from the JSON file your application is a package that requires other packages.

The only difference is that at the moment your project (thus your package) does not have a name.

Let’s fix this!

The way you add a name is by specifying the key name in your JSON file and adding the name of the vendor and the name of the package.

{    "name": "acme/hello-world",    "require": {        "monolog/monolog": "1.0.*"    }}

Usually, when you code a project you do it by creating different versions,

In the vast majority of cases, Composer is able to extract the version from your version control system and you do not need to specify it in the JSON file.

However, if you maintain the project yourself without a VCS you have to specify the version explicitly by adding a version value in your composer.json file.

{
"version": "1.0.0"
}

It is very likely that your favorite VCS also supports the tag and branch feature.

The way it works is that Composer checks your tags and branches and them into a list of options, then it matches against the version constraint you provided.

More about that on the versions and constraints page of the official manual.

Publishing your project

If you have a repository that contains a composer.json file the library is ready to be installed.

Let’s create a new project (let’s say a blog) and install acme/hello-world on it.

// acme/blogProject/composer.json{
"require": {
"acme/hello-world": "dev-master"
}
}

As you can see, since we do not want to publish this project the name is not needed.

What we need though is to describe where to find the hello-world dependency.

We can do this by adding the repositories key to the object.

{    "repositories": [         {            "type": "vcs",            "url": "https://github.com/acme/hello-world"        }    ],    "require": {        "acme/hello-world": "dev-master"    }}

To be able to use hello-world and monolog you just need to use the command

composer install

Have you noticed that we did not specify a package repository for monolog?

The reason is that monolog is published on Packagist, and anything that is published in that package repository is available automatically through Composer

Since Monolog is on Packagist, we can depend on it without having to specify any additional repositories.

If you want to share acme/hello-world via Packagist you only need to visit Packagist and hit the “Submit” button

Conclusion

I can’t stress it enough,

Composer is one of the most important tools if you dream to become a PHP developer.

Everything you need from frameworks to automated test tools is retrieved by Composer.

Having a good grasp of what it does and how it works is fundamental.

In this article, you learned the basics of Composer.

You know now how it works and most importantly what it does.

You should now be able to install packages into your repositories as well as publish your how packages into a VCS and Packagist.

In the following article we are going to delve into the command and the composer.json schema so subscribe to the newsletter if you want to get notified when the new article will be published.

Meanwhile, now that you know how to share your PHP package it might be a good idea to brush up on how to write amazing PHP, and you can learn how to do that by reading the basics of PHP.

Otherwise, it might be of your interest to learn how to develop complex applications using Domain-driven Design.

--

--

Nico Anastasio
CodeX
Writer for

Experienced programmer empowering developers to write flawless code. Explore my blog: anastasionico.uk/blog. Need captivating articles? nico@anastasionico.uk.