Composer Level2: 5 more things like Class Maps, Forking, & Scripts

Published on

Nov 5, 2012

knp

Nov 6, 2012 − Now that you're using Composer to manage your PHP project's dependencies, let's take things to the next level by learning about a few lesser-known features like building class maps (speed!), forking packages, post-install scripts and more!

Yay Composer! <-- That's me yelling recently frantically at any PHP dev I can find (including via talks Symfony Live San Francisco and ZendCon).

If you haven't used Composer yet, darn it, watch our free Composer Screencast over at KnpUniversity already!

For those of you that are comfortable with Composer, I wanted to talk about a few lesser-known, but really fantastic features. These are inspired by real questions I've heard while running around the country doing my one-man composer-and-dancing show (i.e. conference talks).

1) Autoloading & Performance: "I thought class maps were the fastest?"

One thing that Composer handles is autoloading, typically by leveraging the PSR-0 standard. This is awesome because you don't have to worry about autoloading while developing - just add a package and start dominating your code immediately. But this makes for sad pandas because autoloading files becomes really non-performant (i.e. terribly slow in production).

But before you find a dumpster for your computer to live in, an easy solution exists! Internally, you can tell Composer to build a class map of all of the PHP files in your project:

composer.phar dump-autoload --optimize

On the surface, nothing changes. But internally, Composer builds a giant key => value array (class => file location of class) of every class in your project. It lives in vendor/composer/autoload_classmap.php (check it out!) and Composer starts using it immediately.

So, add this to your deploy process, and no more sad pandas! And if you're using capifony to deploy, it takes care of this for you!

2) Running Post-Deploy Scripts

Another question is - "Can I run scripts after my vendors are installed?".

Of course! In fact, doing this is really easy: you can build a PHP class that Composer executes or just have it execute a command-line script. Composer's own documentation covers this topic pretty well, so read about it there: Composer: Scripts

3) "What if I need to fork a library?"

An excellent question! And one that Jordi (aka Seldaek) covered in his recent Composer Presentation at Symfony Live.

Suppose you've found a bug in Symfony that you've fixed in your fork. It's not in core (at least yet), so for now, you need your symfony fork to "replace" the real one.

Doing this is very simple. Suppose that Jordi (i.e. Seldaek) has already forked symfony on GitHub to his own repository at https://github.com/seldaek/symfony. Suppose also that he's already fixed the bug on some new branch called my-patch. The goal is to use Jori's my-patch branch instead of the real Symfony repository at some version (e.g. 2.1.0).

Here's the magic composer.json:

{
    "repositories": [
        {
            "type": "vcs",
            "url":  "https://github.com/seldaek/symfony"
        }
    ],
    "require": {
        "symfony/symfony": "dev-my-patch as 2.1.0"
    }
}

There are two important things:

  1. First, a custom repository (i.e. https://github.com/seldaek/symfony) is added. This is your fork, and it should contain the same composer.json as the real library. In other words, don't rename the package to something else. After this step, any branches/tags on your fork will be available as versions for symfony/symfony, as if they were in the core repository. Sweet!

  2. Update your symfony/symfony require to point to your version (i.e. dev-my-patch) and alias it to the version of the package you were replacing. Without the "as 2.1.0" part, if any other packages in your project depend on symfony/symfony, they'll freak out and your computer will catch on fire (e.g. because they require >=2.1 and have no idea what version "dev-my-patch" represents). By aliasing your new branch as 2.1.0, your new branch will satisfy all those dependencies.

And that's it! And if you want to hear it explained by Mr Composer himself, just check out the above-linked talk from Symfony Live.

4) Can I host private packages on Packagist?

Yes! Wait no! But yes! Packagist is the main public repository for packages. So no, you don't want to put your private packages there :). But you do want to publish them via Satis.

Satis is like a light-weight Packagist: it allows you to easily publish your private package metadata on some server so that you can require your private packages just like your public ones in composer.json. Basically, your full "pool" of available packages become those on the real Packagist + the ones on your internal Satis. And yea, it's basically that simple.

Once again, Composer has this covered pretty darn well in their docs, so read up! Composer: Satis for Private Packages.

And if you really want the nice searching and GUI of Packagist.org, I know a team that simply installed Packagist locally. It's a bit more setup (it uses Solr, for example), but totally doable, and looks cooler when you're finished.

5) What about signing the authenticity of Packages?

This was a big topic at ZendCon 2012 - sometimes as a question and sometimes as a criticism. Right now, there is no way to sign and verify the authenticity of your packages. There is an old issue open on this topic (i.e. it's been a known needed "todo" for awhile), but no big movement on this yet.

But based on the concern - especially from some of the top guys in the ZendFramework community - it seems that this will be tackled sooner or later. If you absolutely need to verify the package integrity right now, you can always fork packages and run them off of an internal Satis. Not ideal I know, but hey, life is still much better than before Composer.

Epilogue: Have you hugged a PHP Developer lately?

As much as any PHP library can, Composer gets me a little choked up! As PHP developers - we seem to not like to get along. And while I don't think that's really true (go to any PHP conference, people are NICE), we seem to rarely work together.

And that's what gets me so excited about Composer. It's not perfect yet, but it's a tool made by PHP for PHP. It only really works if most PHP libraries agree to use it (and they have!) and its main purpose is to further that type of collaboration. Sharing in PHP is finally easy. So find a PHP developer, give him/her a hug, add a line to your composer.json, and start working together on a great library.

Cheers!

Written by

KNP Labs
KNP Labs

Comments