Installing and using Symfony2 with Composer

Published on

Jan 1, 2012

how2tips

Jan 2, 2012 − Are you tired of managing the deps and deps.lock files? Want to install BehatBundle without editing 3 files simultaneously and reading a long list of Mink dependencies that you need to place in deps? Composer to rescue!

Are you tired of managing the deps and deps.lock files? Want to install BehatBundle without editing 3 files simultaneously and reading a long list of Mink dependencies that you need to place in deps? Composer to rescue!

And if you're new to Composer, check out the free Composer Screencast over at KnpUniversity.com.

Composer is a shiny new tool from the Symfony community, which aims to fix the dependency hell that we have right now in Symfony2. Also, Composer will become the core dependency manager for Symfony 2.1 when it's released. But you don't need to wait until then - you can use it for your Symfony 2.0 projects too. And today we'll show you how.

First of all, you need to know that Composer consists of 2 tools:

  • dependency management tool (Composer itself)
  • central package repository (Packagist)

They work together. Packagist holds info about almost any community package and its dependencies and Composer knows how to install them. But the cool part? Even if a library you need hasn't been registered with Packagist or doesn't have a Composer package configuration yet, you can still install it from git, svn, hg or even via Pear.! Yep, that's right, one tool to rule all your project dependencies nevermind where and how they are hosted.

Of course, adding dependencies for libraries that don't have a proper Composer package configuration is not entirely trivial. But fortunately, almost all Symfony2 bundles and community libraries have proper Composer packages nowadays: packagist.org/packages/behat.

Ok, but how to start? We have a surprise for you! The Symfony 2.0 Standard Edition completely integrated with Composer. Just download it from here and put it under your webroot as you do with usual STD edition.

Let's see what we have there. It's the same old STD edition except with a couple of changes. First of all, all dependencies are now managed with a composer.json file:

{
    "require": {
        "php":              ">=5.3.2",
        "symfony/symfony":  ">=2.0.7,<2.1.0-dev",
        "doctrine/orm":     ">=2.1.0,<2.2.0-dev",
        "twig/extensions":  "*",

        "symfony/assetic-bundle":         "*",
        "sensio/generator-bundle":        "*",
        "sensio/framework-extra-bundle":  "2.0.0-dev",
        "sensio/distribution-bundle":     "2.0.0-dev",
        "jms/security-extra-bundle":      "1.0.x-dev"
    },

    "autoload": {
        "psr-0": {
            "Acme": "src/"
        }
    }
}

Secondly, we've updated the bin/vendors script to use Composer internally. It has same old install and update commands, but it calls Composer internally to do dependencies management under the hood.

The third major change is the app/autoload.php configuration:

<?php

use SymfonyComponentClassLoaderUniversalClassLoader;
use DoctrineCommonAnnotationsAnnotationRegistry;

$loader = require_once __DIR__.'/../vendor/.composer/autoload.php';

// intl
if (!function_exists('intl_get_error_code')) {
    $universalLoader = new UniversalClassLoader();
    require_once __DIR__.'/../vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs/functions.php';

    $universalLoader->registerPrefixFallbacks(array(__DIR__.'/../vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs'));
    $universalLoader->register();
}

...

As you might see, there's no bundles or libraries here, only a

require_once __DIR__.'/../vendor/.composer/autoload.php';

call. It's because Composer automatically generates all the needed autoloading routines for you. Yep, forget about editing this file manually... forever! Every bundle will manage its autoloading path on its own and you will just edit composer.json. Look at it once again:

...

    "autoload": {
        "psr-0": {
            "Acme": "src/"
        }
    },
}

see this "autoload" section? It tells Composer where to find your own classes, because it (Composer) already know where to find everything else ;-) So when you need to add another namespace path under src/ like your vendor name, just add it to the composer.json "autoload" section:

...

    "autoload": {
        "psr-0": {
            "Acme":           "src/",
            "YourVendorName": "src/"
        }
    },
}

Ok, enough talk, let's install the Standard Edition:

$ bin/vendors install

Easy, right? But you might say that you had this already with the old bin/vendors script. And you'd be right... NOT:

{
    "require": {
        "php":              ">=5.3.2",
        "symfony/symfony":  ">=2.0.7,<2.1.0-dev",
        "doctrine/orm":     ">=2.1.0,<2.2.0-dev",
        "twig/extensions":  "*",

        "symfony/assetic-bundle":         "*",
        "sensio/generator-bundle":        "*",
        "sensio/framework-extra-bundle":  "2.0.0-dev",
        "sensio/distribution-bundle":     "2.0.0-dev",
        "jms/security-extra-bundle":      "1.0.x-dev"

        "behat/behat-bundle":             "*",
        "behat/mink-bundle":              "*"
    },

    "repositories": {
        "behat/mink-deps": { "composer": { "url": "behat.org" } }
    }

    "autoload": {
        "psr-0": {
            "Acme": "src/"
        }
    },
}

Yep. We've just added MinkBundle and BehatBundle with ALL their dependencies by adding only a few lines of JSON:

    ...
        "behat/behat-bundle":  "*",
        "behat/mink-bundle":   "*"
    },

    "repositories": {
        "behat/mink-deps": { "composer": { "url": "behat.org" } }
    }

Now you might miss adding SahiClient or downloading entire ZendFramework just because of Goutte? Forget about it! Composer will only download needed packages. And when i say needed - i mean only 5 ZendFramework components (~700kb instead of ~20mb) instead of whole ZendFramework.

Just run:

$ bin/vendors update

And you're ready to use BehatBundle with MinkContext inside your project through Goutte/Sahi or Zombie.js. Want to use CommonContexts too? Add:

"behat/common-contexts": "*",

under composer.json / require. Want to use FOSRestBundle? Add:

"friendsofsymfony/rest-bundle": "2.0.0-dev",

Just don't forget to call

$ bin/vendors update

You can find other bundles through Packagist website.

Learn more about Composer and Packagist:

Written by

KNP Labs
KNP Labs

Comments