1/33

Composer
Project Dependency Management for PHP

About Me

Passionate Free Software Developer
  http://github.com/naderman

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

Just launched
 https://www.forumatic.com
 Professional Managed phpBB Hosting

Composer

Managing
Packages vs Dependencies

Package Management in PHP

The Composer Ecosystem

github.com/composer

The Composer Ecosystem

Composer - CLI Tool

  • Easy to use
  • Installs deps per-project
  • Flexible and embeddable
  • Encourages best practices (PSRs, SPDX, semver)

The Composer Ecosystem

Packagist - Package Repository

  • Aggregates PHP libraries
  • Open to all OSS projects
  • Feeds on VCS (git, hg, svn) repositories

The Composer Ecosystem

Satis - Micro Repository

  • Minimalistic (Pirum-like)
  • Useful for closed source code

The Composer Ecosystem

composer/installers

Custom Package Installers for

  • Magento
  • phpBB
  • Drupal
  • SilverStripe
  • Symfony1
  • Wordpress
  • Zend Framework 1
  • CakePHP
  • CodeIgniter
  • FuelPHP
  • Joomla!
  • Kohana
  • Laravel
  • Lithium

Usage Instructions

Using a Composed Project

Cloning into myproject...
cd myproject/
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

01vendor/
02    autoload.php
03    composer/
04    monolog/
05        monolog/
06    symfony/
07        symfony/
08        monolog-bundle/
09    twig/
10        twig/
11        extensions/
12    [...]

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

01{
02    "require": {
03        "silex/silex": ">=1.0.0-dev",
04        "symfony/finder": "2.1-dev",
05        "twig/twig": "1.*",
06        "predis/service-provider": "dev-master"
07    },
08    "require-dev": {
09        "mikey179/vfsStream": "*"
10    }
11}

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

Creating a Package Definition

01{
02    "name": "predis/predis",
03    "type": "library",
04    "description": "Flexible and feature-complete Redis client",
05    "keywords": ["nosql", "redis", "predis"],
06    "homepage": "http://github.com/nrk/predis",
07    "license": "MIT",
08    "authors": [
09        {
10            "name": "Daniele Alessandri",
11            "email": "suppakilla@gmail.com",
12            "homepage": "http://clorophilla.net"
13        }
14    ],
15    "require": {
16        "php": ">=5.3.0"
17    },
18    "autoload": {
19        "psr-0": {"Predis": "lib/"}
20    }
21}

Note: Package Definition === Application/Root Definition

Avoiding version chaos
in your team

composer.lock

  • Lists packages & versions
  • Replaces composer.json
  • Created by composer install (installs your dependencies)
  • Updated by composer update (updates your dependencies)
  • Must be committed in your VCS and shipped with your releases

Benefits

  • Everyone on a team works with exactly the same dependency versions
  • When deploying, all machines run exactly the same dependency versions
  • Users will never get dependency versions that you did not test with

Autoloading

Libraries/projects define their namespaces:

1"autoload": {
2    "psr-0": {
3        "Vendor\\Namespace": "lib/"
4    },
5    "classmap": ["src/", "VeryOld.php"]
6},
7"include-path": ["src/", ""]

Composer builds an autoloader for you:

1vendor/autoload.php

Use the generated autoloader:

01require __DIR__.'/../vendor/autoload.php';
02 
03use Silex\Application;
04use Silex\Extension\TwigExtension;
05 
06use Symfony\Component\Finder\Finder;
07use Symfony\Component\HttpFoundation\Response;
08 
09$app = new Application();
10// ...

Autoloading Tests

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

1# tests/bootstrap.php
2 
3$loader = require __DIR__.'/../vendor/autoload.php';
4 
5$loader->add('My\Test', __DIR__);

Alternative Repositories

01"repositories": [
02    {
03        "type": "composer",
04        "url": "http://private.satis.example.org"
05    },
06    {
07        "type": "vcs",
08        "url": "git://example.org/MyRepo.git"
09    },
10    {
11        "packagist": false
12    }
13]

See docs for more

Depending on packages without composer.json

01"repositories": [
02    {
03        "type": "package",
04        "package": {
05            "name": "vendor/package",
06            "version": "1.0.0",
07            "dist": {
08                "url": "http://example.org/package.zip",
09                "type": "zip"
10            },
11            "source": {
12                "url": "git://example.org/package.git",
13                "type": "git",
14                "reference": "tag name, branch name or commit hash"
15            }
16        }
17    }
18],
19"require": {
20    "vendor/package": "1.0.0"
21}

Note: repositories are only available to the root package

State of the Project

Adoption

  • >3200 packages on Packagist
  • 3'600'000 package installs from Packagist in last 5 months
  • Many early adopters
  • Supported by frameworks/libs
  • Integration by PaaS providers
  • (Integration in apps for plugins)

Roadmap

Wishful Thinking

Look around.

Write small libs.

Share code.

Reuse things.

Reinvigorate PHP

Thank you.

Questions?

@naderman

Feedback

https://joind.in/7075

Bonus Slide: Aliases & Branches

Situation


Solution

01"repositories": [
02    {
03        "type": "vcs",
04        "url": "git://github.com/my/monolog.git"
05    }
06]
07"require": {
08    "symfony/monolog-bundle": "2.0.10",
09    "monolog/monolog": "dev-my-feature-branch as 1.1.0"
10}