Cinan's world

GNU/Linux & free software, howtos, web development, scripts and other geek stuff

Dependency Management in PHP Projects #1

Programmers use many 3rd party libraries in their projects. Problems may occur if programmers are developing a project and they don’t have same libraries or same versions of libraries. Dependency managers solve this problem in an elegant way. If you don’t know about them, I’m sure you’ll love them.

Introduction to Composer

Composer is a multi-platform and easy to use dependency manager for PHP. It’s working on Windows, GNU/Linux, BSD, OS X, whatever. You need PHP 5.3.2+.

Installation is pretty easy, here’s the official howto.

First, go to the project’s root directory and define project dependencies in composer.json file (right, it’s a file written in JSON :) ).

Here’s a real-world example from Gitlist project (licensed under New BSD license):

composer.jsonlink
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
    "require": {
        "silex/silex": "1.0.*@dev",
        "twig/twig": "1.12.*",
        "symfony/twig-bridge": "2.2.*",
        "symfony/filesystem": "2.2.*",
        "klaussilveira/gitter": "dev-master"
    },
    "require-dev": {
        "symfony/browser-kit": "2.2.*",
        "symfony/css-selector": "2.2.*",
        "phpunit/phpunit": "3.7.*",
        "phpmd/phpmd": "1.4.*",
        "phploc/phploc": "1.7.*"
    },
    "minimum-stability": "dev",
    "autoload": {
        "psr-0": {
            "GitList": "src/"
        }
    }
}

The file defines which dependencies the project requires (in require object), dependencies for development environment are listed in require-dev object.

Now we can run composer install. When the task finishes all dependencies are installed in vendor directory and we can use them in the project.

Same versions everywhere

The installing process created composer.lock file. There’s saved a list of installed dependencies along with their versions. This is necessary for keeping same versions of dependencies across all computers where the project has been deployed. If you’re interested in how the file looks like, check this out.

For example, there are two programmers (Programmer#1 and Programmer#2). Both of them have installed dependencies from composer.json above. Then, Programmer#1 wants to upgrade twig from 1.12 to to 1.13 because of new features he desperately needs. So he updates composer, after that runs composer update so dependencies get updated and commits changes to VCS they use (Git, SVN, …). What he actually commits? Only composer.json and composer.lock. In that files is everything what others may need to keep their systems up-to-date. (Actually, just the lock file is needed. Programmer#1 knows Programmer#2 will may want to change dependencies in future, so he commits composer.json.)

Never commit vendor directory.

Next day Programmer#2 pulls changes from VCS and he can see composer files were changed. So he fires up composer update and after few seconds he has exactly same version of dependencies as Programmer#1. It was so easy, just one command.

Summary of what we know so far

  1. First, create a composer.json file in the root directory of a project.
  2. Define project dependencies.
  3. Run composer install.
  4. Commit changes to VCS of your choice. Don’t forget you never commit vendor directory.

If you later change dependencies, edit and save the json file, run composer update and commit json and lock files.

Maybe you’re asking What’s the difference between install and update commands? It’s simple.

  • The update command uses composer.json file, installs dependencies defined in it and in the and it creates/rewrites the lock file.
  • The install command installs dependencies from a lock file. If no lock file exists it behaves like the update command.

In the second part of this article I’ll explain dependency versioning and reveal how the installed dependencies are integrated into projects.

This article was also published on my school blog.

Comments