Dependency Management with Composer:
PHP Reinvented

Nils Adermann

@naderman


Free Software Developer
  https://github.com/naderman

phpBB Development Lead
  https://www.phpbb.com

Composer Co-Author
  https://getcomposer.org

Working at Forumatic
  https://www.forumatic.com

Engine Yard Community Grant
  https://www.engineyard.com

Package and Dependency Management elsewhere

Early 2011

phpBB Plugins

Symfony Bundles

Composer

The Composer Ecosystem

github.com/composer

The Composer Ecosystem

Composer - CLI Tool

The Composer Ecosystem

Packagist - Package Repository

The Composer Ecosystem

Satis - Micro Repository

The Composer Ecosystem

Toran Proxy - Private Repository

https://toranproxy.com

The Composer Ecosystem

composer/installers

Custom Package Installers for

  • MediaWiki
  • OXID
  • phpBB
  • PPI
  • SilverStripe
  • Symfony1
  • TYPO3 Flow
  • Wordpress
  • Zend Framework
  • CakePHP
  • CodeIgniter
  • Drupal
  • FuelPHP
  • Joomla!
  • Kohana
  • Laravel
  • Lithium
  • Magento

Usage Instructions

Using a project

git clone https://github.com/symfony/standard-edition myproject
            
Cloning into myproject...
cd myproject/
            
curl -s http://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 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 project

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

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"
        "symfony/console": "~2.1"
    },
    "require-dev": {
        "mikey179/vfsStream": "*"
    }
}
            

The composer.lock lifecycle

composer.json

composer.lock

vendor/

user defined, configuration, version constraints

composer update

generated, package metadata, specific versions

composer install

dependencies' code and autoloader

composer status

composer.lock

Must be committed in your VCS and shipped with your releases


Benefits

Autoloading

Libraries/projects define their namespaces:

"autoload": {
    "psr-0": {
        "Vendor\\Namespace\\Component": "oldsrc/"
    },
    "psr-4": {
        "Vendor\\Namespace\\Component": "src/"
    },
    "classmap": ["lib/", "VeryOld.php"]
}
            

PSR-0

oldsrc/Vendor/Namespace/Component/MyClass.php
oldsrc/Vendor/Namespace/Component/ThatClass.php
            

PSR-4

src/MyClass.php
src/ThatClass.php
            

Autoloading

Composer builds an autoloader for you:

vendor/autoload.php
                

Use the generated autoloader:

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

use Silex\Application;
use Silex\Extension\TwigExtension;

use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpFoundation\Response;

$app = new Application();
// ...
                

Regenerating the autoloader

composer dump-autoload
composer dump-autoload --no-dev --optimize

Semantic Versioning

semver.org

MAJOR . MINOR . PATCH

1 . 2 . 3

MAJOR . MINOR . PATCH

Breaks           Features           Fixes  

Dev
  -> 0.1.0

Fixes
  -> 0.1.1

Breaking changes
  -> 0.2.0

First stable
  -> 1.0.0

Fixes
  -> 1.0.1

Fixes
  -> 1.0.2

New features
  -> 1.1.0

Breaking changes
  -> 2.0.0

Version Constraints

Exact Match

1.0.0   1.2.3-beta2   dev-master

Range

1.0.*   2.*

Unbounded Range (BAD)

>=1.0

Operators

, = AND    | = OR

Next Significant Release

~1.2   =   >=1.2.0,<2.0.0

Next Significant Release ~

~1.2   =   >=1.2,<2.0.0

~1.2.3   =   >=1.2.3,<1.3.0

Next Significant Release ^

^1.2.3   =   >=1.2.3,<2.0.0

Libraries should use ~ or ^

Composer Stabilities

Stabilities

dev -> alpha -> beta -> RC -> stable

Tags

2.0.2 -> stable

2.0.0-beta2 -> beta

Branches

2.0 -> 2.0.x-dev (dev)

master -> dev-master (dev)

lala-feature -> dev-lala-feature (dev)

Requiring Stability

"minimum-stability": "beta"

^1.2.3@alpha

>=1.2.3,<3.0.0@beta

composer update

--no-dev
--prefer-source
--prefer-dist
--prefer-stable
--prefer-lowest
--ignore-platform-reqs

Installing Satis

php composer.phar create-project composer/satis --stability=dev --keep-vcs

Configuring Satis

{
    "name": "My Repository",
    "homepage": "http://packages.example.org",
    "repositories": [
        {"type": "vcs", "url": "http://github.com/company/repo1"},
        {"type": "vcs", "url": "http://svn.example.org/repo"},
        {"type": "vcs", "url": "http://github.com/company/repo2"}
    ],
    "require-all": true
}
                

Configuring Satis

{
    "name": "My Repository",
    "homepage": "http://packages.example.org",
    "repositories": [
        {"type": "vcs", "url": "http://github.com/company/repo1"},
        {"type": "vcs", "url": "http://svn.example.org/repo"},
        {"type": "vcs", "url": "http://github.com/company/repo2"}
    ],
    "require": {
        "company/package": "*",
        "company/package2": "*",
        "company/package3": "2.0.0"
    }
}
                

Configuring Satis

{
    "archive": {
        "directory": "dist",
        "format": "tar",
        "prefix-url": "https://amazing.cdn.example.org",
        "skip-dev": true
    }
}
                

Building the Satis Repository

php bin/satis build config.json web/

Using a Satis Repository

"repositories": [{
    "type": "composer",
    "url": "http://p.example.org/"
}],
            

System-wide Satis Repository

*nix: /home/example/.composer/config.json

Windows: C:\Users\example\AppData\Roaming\Composer\config.json

{
    "repositories": [
        {
            "type": "composer",
            "url": "http://p.example.org/"
        }
    ]
}
            

Use composer config -g -e to open the file

PHP Reinvented?

PHP Depenency Management Reinvented

User describes system state

Tool maintains system state

Familiar?

Packagist Growth

PHP Reinvented: Goals

Methods

New frameworks

Symfony2, Laravel, Silex, Lithium ...

Single purpose libraries

Assetic, Guzzle, Monolog, Twig, Imagine, ...

Faster innovation cycle

Look around.

Write small libs.

Share code.

Reuse work.

Reinvigorate PHP

Find Out More

Thank you.

Questions?

@naderman