PHP
Article
By Claudio Ribeiro

Re-Introducing Composer – the Cornerstone of Modern PHP Apps

By Claudio Ribeiro
Help us help you! You'll get a... FREE 6-Month Subscription to SitePoint Premium Plus you'll go in the draw to WIN a new Macbook SitePoint 2017 Survey Yes, let's Do this It only takes 5 min

This article was peer reviewed by Wern Ancheta. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

This popular article was updated on May 21st 2017 to provide a more comprehensive introduction into an essential, modern tool.


In this article, we will tackle the basics of Composer, and what makes it such a powerful and useful tool.

Before we go into detail, there are two things that we need to have in mind:

  • What Composer is:

    As we can see on their website: “Composer is a tool for dependency management in PHP. It allows you to declare the libraries your project depends on and it will manage (install/update) them for you.”

  • What Composer is not:

    Composer is not a package manager. It deals with packages but in a “per project” way. While it provides a global installation option, it does not install anything globally by default.

Essentially, Composer allows you to declare and manage every dependency of your PHP projects.

Let’s now install Composer so we can see it in action.

Composer Logo

Installation

There are two ways of installing Composer: locally and globally. Because Composer is such a useful and widespread tool, I always recommend installing it globally, as you’ll probably be working on more than one project at once.

Note that if you use an environment like Homestead Improved, it’s installed globally by default. If you’re unfamiliar with Vagrant and Homestead, this post will clear things up, and if you’d like to dive deeper, this book will reveal some wild mysteries to you.

To install Composer, follow the instructions for your operating system.

If you’re on a Unix system, after installing it you can run the command:

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

This moves the composer.phar file to a directory that’s on your path (the location of your filesystem where the OS looks for executable files by default). This way, you can use just the composer command instead of composer.phar.

Running the composer command shows the information page:

Composer main information

Some of Composer’s more useful commands are:

  • composer help <command> – will show the help page for a given command.
  • composer self update – Updates composer to the latest available version.
  • composer search – Searches for packages.
  • composer status – Shows a list of dependencies that have been modified locally. If we install something from the source (using the --prefer-source option), we will end up with a clone of that package in the /vendor folder. If we make some changes to that package, the composer status command will show us a git status for those changes.
  • composer diagnose – Diagnoses the system for common errors. This is especially useful for debugging, as it checks for things like connectivity to Packagist, free disk space, and git settings.

We will focus our attention on composer init, composer create-project and composer require.

Using Composer

To manage dependencies in a project, Composer uses a json file. This file describes all the dependencies, and holds some metadata as well.

In this example we will create a new PHP project in which we will need PHPUnit for our unit testing. There are several ways to use Composer to manage this dependency.

  • composer init will launch the wizard. The wizard will guide us through the generation of our composer.json file.

  • composer search phpunit will search for all packages available that have the keyword phpunit. After we choose the package we want, we can then use composer require <package>. This command will not only create the composer.json file, it will also download all the dependencies specified.

  • Manually write the composer.json file (not recommended – easy to slip up with syntax and brings no apparent benefits). Here’s an example:

{
    "require": {
        "phpunit/phpunit": "^4.8"
    }
}
  • The require key takes objects that map package names (e.g. phpunit/phpunit) to version constraints (e.g. 4.8). Composer uses this information to search for the right set of files in package “repositories” that you register using the repositories key (more info here) or on Packagist, the default package repository which we’ll discuss a little later.

If you used composer init or the manual method, you need to run composer install. This will download all the dependencies needed for the packages described in the composer.json file.

Note that writing the file manually and then running composer install is the same as running composer require <package>.

Using the composer require <package> approach is a recommended best practice.

The first time you run the composer install command, the dependencies are downloaded and their installed versions are registered in the composer.lock file. The next time someone runs composer install on the project, it will not get the latest available package versions, but the ones that are registered in the composer.lock file. This way, Composer ensures that your project doesn’t break due to unexpected code changes in newer versions of the packages.

Updating Your Packages

The composer.lock file ensures that everyone in the project uses the same version of the packages by not allowing newer versions to be downloaded.

If for any reason we want to stick to a particular version, than we should mention the appropriate version in the composer.json file. For example:

  {
      "require": {
          "phpunit/phpunit": "4.8"
      }
  }

But what if we want to update our dependencies to the latest versions?

To update dependencies, Composer provides the composer update command. This command will not only download the latest versions of our dependencies, it will also update the composer.lock file to the new versions. Running composer update is actually the same as deleting composer.lock and then re-running composer install.

It is generally recommended to commit the composer.lock file into the version control system when working on a project (app) and to ignore it when working on a package. A package should always strive to use the latest version of its dependencies, while an app is generally more fragile. More discussion about this and alternative approaches here.

The Vendor Folder

Composer downloads all dependencies into the /vendor folder, which it creates if it doesn’t exist. It also creates a vendor/autoload.php file which looks something like this:

<?php

// autoload.php @generated by Composer

require_once __DIR__ . '/composer/autoload_real.php';

return ComposerAutoloaderInit7a731d2067108a4739c3dd65be722f17::getLoader();

Once you include or require this file in your code, you can use all the functionality provided by your dependencies. This is as simple as adding the following snippet to your code:

require __DIR__ . '/vendor/autoload.php';

Autoloading

The autoloading provided by Composer to access the project’s dependencies is very useful, and can also be used to access our own application’s code. To do this, we need to register our code in the composer.json file using the autoload key.

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

First, Composer will register a PSR-4 autoloader for the Foo namespace.

Then, we map the Foo namespace to the /src folder. The /src folder should be at the same level as the /vendor folder (root of the project). After this, we need to re-generate the vendor/autoload.php file. Composer provides a command for this: composer dump-autoload.

Pro-tip: composer du would also work, because composer runs any command which is uniquely identified by its first few letters. In dump-autoload‘s case, there’s no other command in the Composer namespace that starts with du, so Composer knows that’s the one we want. This works with all Composer commands.

This way we are adding our own code to the autoloader. In addition to PSR-4 autoloading, Composer also supports PSR-0, classmap, and files autoloading. Check out the documentation for more information on autoloading with Composer.

--ADVERTISEMENT--

Configuration Values and Minimum Stability

Sometimes, your project will depend on packages that don’t have a stable version released. Composer defaults to preventing unstable packages from being installed.

In those cases, it’s easy to add the minimum-stability flag into the composer.json file, and Composer will allow their installation.

composer config minimum-stability dev

Almost all configuration values can be edited from the command line, as explained in this section of the docs.

Global Packages

Some packages can come in handy if installed globally. Case in point, tools like Spress and Laravel can have command line tools for generating new projects, re-running some common commands, etc. Likewise, a test suite like PHPUnit can benefit from being runnable from any part of the system, and makes the project it’s testing much lighter.

In general, packages can be installed globally with the global option, like so:

composer global require phpunit/phpunit

However, according to some, this is considered harmful. Your mileage may vary – we’ve generally found that when a professional and modern approach of developing in an isolated environment is followed, global require is 100% safe to use.

Packagist

Packagist

Packagist is Composer’s main repository. This is where all the Composer packages are aggregated, which means that when we execute composer search <package> we are actually searching Packagist. The Packagist website also has information on all the packages and a useful search and sort engine. This way, PHP developers don’t have to spend days searching for packages on Github.

Not only does Packagist aggregate PHP packages, it also encourages PHP developers to submit their own packages, strengthening the community.

Submitting a Package to Packagist

Let’s create a simple PHP package so we can see how easy it is to submit it to Packagist. We are going to create a simple class that converts inches to centimetres and centimetres to inches. Let’s create a /src/Converter/Converter.php file. Inside this file, we are going to have the following code:

<?php 

namespace Converter;

class Converter
{
    public function convertToCm($value)
    {
        return $value * 0.3937;
    }

    public function convertToInch($value)
    {
        return $value * 2.54;
    }
}

As you can see, a very simple class. The second step is to navigate to the root of our project and run the composer init command to run the wizard and generate the composer.json file.

Run init on our package

The last thing we need to do is add the autoload key to our composer.json file. The final file should look like this:

{
    "name": "dailymatters/inch-conv",
    "description": "Inch To Cm converter",
    "type": "library",
    "license": "creative commons",
    "authors": [
        {
            "name": "DailyMatters",
            "email": "email@gmail.com"
        }
    ],
    "minimum-stability": "dev",
    "require": {},
    "autoload": {
        "psr-0": {
            "Converter": "src/"
        }
    }
}

Let’s now run composer install so that our autoloader can be created. Then, let’s test our package. In the root of our project, let’s create an index.php file.

<?php

require_once '/vendor/autoload.php';

use Converter\Converter;

$conv = new Converter;

$result = $conv->convertToCm(1);
echo $result;

$result = $conv->convertToInch(1);
echo $result;

As you can see, we are using the require_once '/vendor/autoload.php'; line to autoload our class and then using it to do some conversions.

Testing it on the command line with php index.php should produce the desired result.

To submit this package to Packagist, we need to push it to a Github repo. Then, we sign in to Packagist using our Github account, hit Submit, and point to our newly created Github repo.

Remember to update Packagist whenever you update your repo in Github! You can either configure Packagist to do it automatically, or you can access your package on Packagist and click the Update button. This way, your package in Packagist will always mirror your package’s Github state.

Conclusion

Composer has revolutionized the way PHP developers work, and promises to continue doing so. It’s a powerful and essential tool for any PHP developer’s tool belt, and the cornerstone of many modern PHP applications.

Are you using Composer? Is anything about it unclear? Let us know in the comments below.

Login or Create Account to Comment
Login Create Account
Recommended
Sponsors
Get the most important and interesting stories in tech. Straight to your inbox, daily.Is it good?