Motorcycle Adventures and Free Software
Henri Bergius
Biker, free software consultant, neogeographer

See also my JavaScript blog, The Universal Runtime

This entry was posted on 2011-11-02 00:01:06 UTC in 60° 10.188 N 24° 56.292 E Helsinki, FI to

Composer solves the PHP code-sharing problem

  1. Easy for users
  2. Easy for developers
  3. Where are we now?

In PHP we've had a lousy culture of code-sharing. Because depending on code from others as been tricky, every major PHP application or framework has practically had to reimplement the whole world. Only some tools, like PHPUnit, have managed to break over this barrier and become de-facto standards across project boundaries. But for the rest: just write it yourself.

But now Composer, and its repository counterpart Packagist, promise to change all that. And obviously new conventions like PHP's namespacing support and the PSR-0 standard autoloader help.

Composer is heavily inspired by NPM which has built a strong culture of code-sharing and easy deployment in the Node.js community.

Easy for users

With Composer, managing dependencies in your project is very easy. Simply create a composer.json file where you state your dependencies, and let the package management system worry about the rest.

Packages that are registered with packagist.org are obviously easiest to depend on, but you can also state packages coming from custom repositories (like your company's internal version control system), or PHP extensions that you need.

Here is for example the composer.json from the Midgard PHPCR provider:

{
    "name": "midgard/phpcr",
    "type": "library",
    "require": {
        "php": ">=5.3.0",
        "ext-midgard2": ">=10.05.5",
        "phpcr/phpcr": ">=2.1.0-beta1"
    }
}

With this file, Composer knows that our PHPCR provider runs only on PHP 5.3 or newer (as it uses namespaces), and that it needs the Midgard PHP extension and the PHPCR interface classes to be available.

Now installing the project is easy:

$ wget http://getcomposer.org/composer.phar 
$ php composer.phar install

How about autoloading? Traditionally PHP required you to manually include or require all files you wanted to use in your code, with the possibility to write an autoloader to handle it automatically when you call an undefined class. But managing these autoloaders is also a chore.

Composer helps here too, by automatically generating an autoloader that will be able to load your own code, and the code from all your dependencies. So you can get rid of your own autoloaders and include statements, and just include the Composer-generated autoloader in your code:

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

After this all the classes you've stated your application needing will be available.

Easy for developers

While ease-of-installation is important, it isn't enough to build an ecosystem. The other thing that has to be easy is publishing code. Basically: if you've written a piece of functionality in PHP that you could see yourself using in another project, it should be effortless to publish it as a library.

This is where approaches like PEAR mostly failed, by making it too cumbersome to define your packages, to build them, and to upload them to the repository.

With Composer this is very easy. You again define a composer.json for your package, and push that to your project's Git repository. Then just register the Git repository URL with packagist.org.

After this Packagist will spider your repository and make it available as a package.

Publishing new versions is very easy: simply keep your composer.json up-to-date, and tag your releases in Git.

Where are we now?

It is still early days for Composer, and the project is being worked on at a hectic pace. However, it is already good enough for managing dependencies to modern, PSR-0 compatible libraries.

What I would like to see happen next is support for custom package roles and autoloaders. This would allow us to handle more specific cases, like for example installation of Midgard MVC components and their non-namespaced autoloading needs. After that we should be able to get rid of our custom installer code and just join the Composer crowd.

But if your code is already fully namespaced, this is a great time to get started with Composer.

Sponsored links

save money using, phone card

Comments:

Aapo Talvensaari on 11/01/11 23:22:13

I see, but PHP is a hybrid language. Not all components are provided as classes. Many are just a collection of (namespaced) functions. Some even run code just by including them (I know, this is bad, but there are certainly use cases for it). And the best are usually made as PHP extensions (coded in C or C++), many times just wrapping the plain old C-libs. Also does it support Traits? Do you know how this works in these different scenarios. If it only works with OO-code, I don't see it as a solution (well, for some it might be a solution). I don't particularly like that there seems to be a movement to push PHP as a Java / .NET clone. I like PHP as a glue, I like to hack PHP, I don't need another enterprise level system. What do you think? (for example PHPUnit has no use outside classes and objects).

Henri Bergius on 11/02/11 08:12:15

There are no reasons why you couldn't use Composer for managing non-namespaced, or non-OOP code. It is just than then you won't benefit from namespaces and the Composer-generated autoloader and have to manage your includes in the traditional way.

Aapo Talvensaari on 11/02/11 08:20:44

Is there benefits then in using it (in non-oo scenario)? I have to look at the composer / packagist more...

Henri Bergius on 11/02/11 09:14:39

The benefit is that it can manage your project's dependencies and install them, regardless of whether they're OOP or non-OOP. And it does this in a better way that PEAR, for instance all dependencies are installed inside your project, not to some global directory like PEAR. Way easier when you have multiple projects on a single machine.

Aapo Talvensaari on 11/02/11 11:42:25

Thanks. I will definitely check if this works for me. It still concerns me that in PHP world, not all dependencies are in PHP-files (or phar-archives). I mean, there are usually dependencies on PHP extensions, PHP configuration, mod_rewrite, server software (like mysql, redis, memcached), and so on. I know that composer doesn't try to solve the whole dependency problem. I have to look if this is worth it. I mean, more tools also means more complexities - it's balancing act, whether the tool really brings benefits that are greater than its drawbacks. I need more convincing, ;-).

cordoval contact on 11/03/11 16:35:06

interesting way of doing comments, it mentions buzz and it is going to be deactivated so i don't know if your comment feature is going to continue working...

about composer blog post: I think is great, however, it is not ready right on SE right? i think I will start using it when it hits SE... also it would be great to see a hybrid example with old and new libraries and composer working on both.

Thanks!

Greg Knapp on 11/08/11 11:22:32

This isn't a criticism but I found it amusing you've opted for a JSON configuration file for a PHP tool. Your JSON class uses json_decode() to read this into a PHP array structure. Which begs the question, why go with JSON instead of raw PHP? I'm sure the majority of PHP devs are familiar with JSON. Just a thought.

Post a comment:

Post a comment via Google Buzz

Back