Composer Makes Copy-Pasting Libraries Obsolete
For years the PHP answer to “how do I use this library” was to download a zip, drop it in a folder, and wire up an include somewhere. Update it later? Download the zip again and hope you remember which files you touched. Composer replaces all of that. It’s a dependency manager for PHP, still labeled 1.0.0-alpha, but it already does the job well enough that I’d reach for it on any new project. The introduction in its docs describes it plainly: you declare the libraries your project needs, and Composer works out which versions to install and downloads them into your project. It’s openly inspired by npm and Bundler, and PHP has needed something like it for a long time.
composer.json
Everything starts with one file in your project root. You list what you depend on:
{
"require": {
"monolog/monolog": "1.0.*"
}
}
A package name is a vendor plus a project, like monolog/monolog, which keeps two people’s “json” library from clashing. The version there, 1.0.*, means any release in the 1.0 series. You can also pin an exact version, give a range with the comparison operators, or use a wildcard. Then you run install and Composer resolves the whole dependency tree, including the dependencies of your dependencies, and fetches them.
install versus update
These two commands trip people up, so it’s worth being clear. The basic usage guide spells out the difference. When you run this:
$ php composer.phar install
Composer looks for a composer.lock file. If one exists, it installs the exact versions recorded there and ignores what composer.json might now allow. If there’s no lock file, it resolves from composer.json and writes one. So install is the reproducible command: it gives everyone the same versions.
$ php composer.phar update
Update is the opposite. It re-resolves against composer.json, fetches the latest versions that still satisfy your constraints, and rewrites composer.lock with whatever it landed on. The rule I follow: run update when you actually mean to move versions, and run install every other time.
Commit the lock file, ignore the vendor directory
Two habits make Composer pay off, and they surprise people because they pull in opposite directions.
Commit composer.lock. The docs put it in bold: commit your lock file into version control along with composer.json. Because install honors the lock file exactly, committing it means your teammates, your CI server, and production all build against the identical set of versions you tested. Without it, everyone runs whatever was newest the day they cloned.
Don’t commit the vendor directory. Composer installs libraries into a folder called vendor, and the general recommendation in the FAQ on committing dependencies is not to check it in. Add it to your .gitignore and have everyone run install instead. The reasons are a bloated repository, duplicated history of every dependency, and the mess that git-installed packages create by showing up as fake submodules. So the counterintuitive setup is: the lock file goes in git, the code it points to does not.
The autoloader you get for free
The other thing that made me switch is that you stop writing include lines. For libraries that ship autoload information, Composer generates a single file, and you include it once:
<?php
require 'vendor/autoload.php';
$log = new Monolog\Logger('app');
That’s it. Every installed library’s classes are now autoloadable. You can register your own code the same way by adding an autoload section to composer.json pointing a namespace at a directory, then re-running install to regenerate the file. No more hand-maintained require blocks at the top of every script.
Where the packages come from
Most of what you’ll install lives on Packagist, which the docs call the main Composer repository. It’s the central index Composer searches by default, so once a library is published there you can require it by name without any extra configuration. Any open source PHP project that uses Composer should publish there, and browsing it is a decent way to find libraries in the first place.
Worth using at alpha?
It’s fair to be wary of software that still calls itself alpha, and the format has been shifting: the changelog around this summer’s releases mentions changes to the lock file format and to defaults like minimum-stability. But the core workflow, declare in composer.json, commit the lock, ignore vendor, include the autoloader, has been stable and is clearly the direction the whole ecosystem is heading. I’d start using it now on new work and let the tool catch up to 1.0 around you.