Jordi Boggiano
@seldaek
http://nelm.io/


Dependency Management
with Composer

Belgian living in Zürich, Switzerland

Building the internet for 10 years
 http://seld.be

Symfony2, Composer and other OSS contributions
 http://github.com/Seldaek

Working at Nelmio
 http://nelm.io
 Symfony2 & frontend performance consulting

Composer

Managing
Packages vs Dependencies

The Composer Ecosystem

github.com/composer

The Composer Ecosystem

Composer - CLI Tool

The Composer Ecosystem

Packagist - Package Repository

The Composer Ecosystem

Satis - Micro Repository

Usage Instructions

Using a Composed Project

git clone https://github.com/symfony/standard-edition myproject
            
Cloning into myproject...
cd myproject/
            
curl -s https://getcomposer.org/installer | php
            
All settings correct for using Composer Composer successfully installed to: /home/bob/myproject/composer.phar Use it: php composer.phar

Using a Composed Project

php composer.phar install
            
Installing from lock file - Package twig/extensions (dev-master) Downloading Unpacking archive Cleaning up [...] - Package twig/twig (1.8.0) Downloading Unpacking archive Cleaning up - Package symfony/symfony (dev-master) Downloading Unpacking archive Cleaning up Generating autoload files

Using a Composed Project

vendor/
    autoload.php
    composer/
    monolog/
        monolog/
    symfony/
        symfony/
        monolog-bundle/
    twig/
        twig/
        extensions/
    [...]
            

One-line Project Initialization

php composer.phar create-project <package> [<dir>] [<version>]

php composer.phar create-project symfony/framework-standard-edition
            

Downloading Project Dependencies

composer.json

{
    "require": {
        "silex/silex": ">=1.0.0-dev",
        "symfony/finder": "2.1-dev",
        "twig/twig": "1.*",
        "predis/service-provider": "dev-master"
    },
    "require-dev": {
        "mikey179/vfsStream": "*"
    }
}
            

Source install: With install --prefer-source it clones/checks out the code.

Dev requirements: With install --dev they are included.

Version Constraints

Exact

"acme/example": "1.0.0"
"acme/example": "dev-master#26622600f"
            

Ranges

"acme/example": ">=1.0.3"
"acme/example": ">=1.0.3,<1.2"    // , means AND
"acme/example": "1.0.*"           // >=1.0 AND <1.1
            

Next Significant Release

"acme/example": "~1.0"            // >=1.0 AND <2.0
"acme/example": "~1.1"            // >=1.1 AND <2.0
"acme/example": "~1.2.0"          // >=1.2.0 AND <1.3.0
"acme/example": "~1.2.3"          // >=1.2.3 AND <1.3.0
            

Creating a Package Definition

{
    "name": "predis/predis",
    "type": "library",
    "description": "Flexible and feature-complete Redis client",
    "keywords": ["nosql", "redis", "predis"],
    "homepage": "http://github.com/nrk/predis",
    "license": "MIT",
    "authors": [
        {
            "name": "Daniele Alessandri",
            "email": "suppakilla@gmail.com",
            "homepage": "http://clorophilla.net"
        }
    ],
    "require": {
        "php": ">=5.3.0"
    },
    "autoload": {
        "psr-0": {"Predis": "lib/"}
    }
}
            

Note: Package Definition === Application/Root Definition

Note: No version is defined since it is inferred from VCS info

Avoiding version chaos
in your team

composer.lock


Benefits

Autoloading

Libraries/projects define the way they should be loaded:

"autoload": {
    "psr-0": {
        "Acme\\Example": "src/"
    },
    "classmap": ["src/", "Class.php"]
},
"include-path": ["src/", ""]
            

Composer builds an autoloader for you:

vendor/autoload.php
                

Use the generated autoloader:

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

use Acme\Example\Foo;

$foo = new Foo();
// ...
                

Autoloading Tests

Add your own namespaces for testing purposes in PHPUnit's bootstrap:

# tests/bootstrap.php

$loader = require __DIR__.'/../vendor/autoload.php';

$loader->add('My\Test', __DIR__);
            

Alternative Repositories

"repositories": [
    {
        "type": "composer",
        "url": "http://private.satis.example.org"
    },
    {
        "type": "vcs",
        "url": "git://example.org/MyRepo.git"
    },
    {
        "packagist": false
    }
]
            

See docs for more

Depending on packages without composer.json

"repositories": [
    {
        "type": "package",
        "package": {
            "name": "vendor/package",
            "version": "1.0.0",
            "dist": {
                "url": "http://example.org/package.zip",
                "type": "zip"
            },
            "source": {
                "url": "git://example.org/package.git",
                "type": "git",
                "reference": "tag name, branch name or commit hash"
            }
        }
    }
],
"require": {
    "vendor/package": "1.0.0"
}
            

Note: repositories are only available to the root package

Wrap up

Install dependencies (from lock file)

composer install
            

Update deps to their latest versions

composer update
            

Install dependencies in production

composer install --optimize-autoloader
composer install -o
            

State of the Project