Using Composer to manage project dependencies

        Web Design, Web Development

WASHINGTON, DC Web development company – Herndon, Virginia

Composer is a CLI PHP package management tool that can be used in any size project to decouple the core functionality and third-party frameworks. It is used by many popular projects and frameworks, such as phpBB 3.1 and Drupal 8, which are as of yet unreleased, and Symfony2 and Laravel, among others.

The main advantage of using Composer is that you don’t have to clutter your own repository with 3rd-party code and constantly have to check to make sure it is up to date. All you do is specify the dependencies you would like to include and run a command on the command line. Composer does all of the work for you: finding and downloading the specified version of each dependency, configuring an autoloader so you don’t have to manually include a bunch of files, and replacing old versions of the package with updated versions (when you run the update command).

There are two sides to using composer: one is to make your PHP project a composer-ready package, and the other is to include PHP packages into your project. Of course, a composer package can depend on other composer packages, and on the other hand it isn’t required that the software including composer packages be a package itself.

Whether you wish to make your project a composer package, or you would like to include other packages into your project, you will need to create a new JSON file in the top-level directory of your project. The file must be called composer.json. Depending on your goals, this file may contain information about your project, and it will also house a list of packages that your project may depend on.

Note that, according to the Composer website, every project is a package. However, I will be referring to nameless packages as projects to remove confusion.

For the first use case, which is using composer to only include 3rd-party packages but not making the project itself an installable package, we will look at the composer.json file in the phpBB repository:

{
	"minimum-stability": "beta",
	"require": {
		"lusitanian/oauth": "0.2.*",
		"symfony/config": "2.3.*",
		"symfony/console": "2.3.*",
		"symfony/dependency-injection": "2.3.*",
		"symfony/event-dispatcher": "2.3.*",
		"symfony/http-kernel": "2.3.*",
		"symfony/routing": "2.3.*",
		"symfony/yaml": "2.3.*",
		"twig/twig": "1.13.*"
	},
	"require-dev": {
		"fabpot/goutte": "1.0.*",
		"phpunit/dbunit": "1.2.*",
		"phpunit/phpunit": "3.7.*",
		"phing/phing": "2.4.*",
		"squizlabs/php_codesniffer": "1.*"
	}
}

On line 2, we see the minimum-stability option, which allows us to specify the lowest allowed stability of dependencies we want to install. If you look at the lines below it, you will see version numbers with asterisks, which basically says to pull the latest version that matches the rest of the version string. If the minimum stability is beta and there is a new alpha release in a Symfony2 component, it will be ignored and the most recent beta-quality release will be used.

The next option, "require" is where you will list the vast majority of the dependencies your project will need. As you can see, phpBB uses several Symfony2 framework components, the Twig template system, and an OAuth library. These will be automatically fetched and downloaded from the git repository using the specified version numbers to get the correct version.

Lastly, the "require-dev" option is used to specify dependencies that your project needs only for people developing the project. In our example, we require Goutte, a web scraper used for functional tests, PHPUnit and DBUnit, which is a unit test framework, Phing, which is a PHP project build system, and PHP CodeSniffer, which is used to make sure the correct coding style guidelines are being used across the entirety of the code base.

You are able to specify when installing and updating dependencies whether or not to include the dev dependencies. The reason we separate those dependencies is because the average end user is not going to need them for day-to-day use of the software. If we always included those in the package, the project would be larger and that code would just be taking up space without being used. By using Composer, we are able to include only what we need.

Let’s take a look at another composer.json file. This time, let’s look at the HttpFoundation component in Symfony2:

{
    "name": "symfony/http-foundation",
    "type": "library",
    "description": "Symfony HttpFoundation Component",
    "keywords": [],
    "homepage": "http://symfony.com",
    "license": "MIT",
    "authors": [
        {
            "name": "Fabien Potencier",
            "email": "fabien@symfony.com"
        },
        {
            "name": "Symfony Community",
            "homepage": "http://symfony.com/contributors"
        }
    ],
    "require": {
        "php": ">=5.3.3"
    },
    "autoload": {
        "psr-0": { "Symfony\\Component\\HttpFoundation\\": "" },
        "classmap": [ "Symfony/Component/HttpFoundation/Resources/stubs" ]
    },
    "target-dir": "Symfony/Component/HttpFoundation",
    "minimum-stability": "dev",
    "extra": {
        "branch-alias": {
            "dev-master": "2.5-dev"
        }
    }
}

As you can see, there is a lot more information included in this file than in the phpBB one. That is because this component is itself a package, whereas phpBB is just a project that includes packages. As such, we have to define several items that are used by Composer to determine that this is the package we want.

First, we have the "name" parameter that is the most important part. This is primarily what makes your package installable. By convention, package names are all lowercase and use dashes to separate words. However, names are case-insensitive. If you aren’t sure what to use as a package name, it is recommended that you use your GitHub username as the vendor (i.e. the part before the /) and the repository name as the package name (i.e. the part after the /).

Next, we have the "type" option, which defaults to library. You can check the documentation I just linked in order to determine what type your package should be.

I won’t go in depth explaining description, keywords, homepage, license, and authors because they are all fairly self-explanatory.

The “require” option lets you choose specific version constraints for things that aren’t actually packages. For instance, PHP itself isn’t a Composer package but you can still require that the person installing the package, in this example, has at least version 5.3.3.

Composer automatically generates a class map so that you can include one file and be able to automatically load any class that was installed in a composer Package. The "autoload" option lets you add your own code or other projects that aren’t managed by composer to the autoloader so that it is all in one place. You can also use it in conjunction with the next option to make sure the autoloader is pointing to the correct directory, as is done in the example.

The "target-dir" option is used to tell composer where to put the files when it downloads them. By default it just starts in the ./vendor/{vendor}/{package} directory and puts all of the files there. However, in the case of Symfony components, they go into a different directory than the default.

The “extra”:”branch-alias” option is a bit more in-depth than I would like to go in this article. You can read all about it here.

There are many, many more options available to customize exactly how your package will work. All of it is available in the Composer documentation on their website. I hope this article has helped you understand how to get started using Composer in your own project, whether using it only to include other packages, or to make your own package.

As a final parting example, I’ll show you a simple package I created almost a year ago: LoadTimer. As you can see, the composer.json file contains only three items: the name, the license, and the PHP version. I don’t have any dependencies, so I don’t need a require statement. To use the package, just add "imkingdavid/load-timer": "dev-master" to your requirements and run the composer update command.

Speaking of which, I forgot to mention how to run Composer. First, you need to go to getcomposer.org and follow the instructions to download the composer.phar file. This is the file you will be using to run your CLI commands. You can place it just about anywhere, but keep track of where it is because you will need to input its path when running the commands. It is usually helpful to put a copy near each of the projects for which you will be managing dependencies. One composer.phar file will work for any installation, but having several copies can make it easier to find one.

To first install the dependencies, open your command line to the folder into which you want the vendor folder installed. Then run the following command:

> path/to/php.exe path/to/composer.phar install --no-dev

Note that <code>–no-dev</code> will tell it to skip the development dependencies. If you do not include that flag, it will install those dependencies by default. To see all of the options and flags on the <code>install</code> command, view the http://getcomposer.org/doc/03-cli.md#install documentation

The update command is to be used after the composer.lock file has been created (which occurs during installation). It has the same syntax, simply replacing install with update. You can view usage of it and other commands in the documentation.


About Luis Cuellar

Co-founder and Agile Coach, in charge of leading, managing and coaching agile project teams to achieve a high level of performance and quality in delivering projects that provide exceptional business value to government agencies and nonprofit organizations.
This entry was posted in Web Design, Web Development and tagged , , . Bookmark the permalink.

Comments are closed.