Composer

Composer is a tool for managing your dependencies in PHP. It allows us to declare library dependencies and it will install them for us, into our project. We will learn

  • how to install Composer
  • use in new or existing project
  • create and publish our of own package

Installation

Composer is distributed as runnable .phar file, and you can download the latest version here.

Linux

If you're using Linux, it's suggested to install the Composer using its installer

$ curl -s http://getcomposer.org/installer | php

By copying into folder that is in system's PATH

$ mv ./composer.phar ~/bin/composer # or /usr/local/bin/composer

Composer becomes globally accessible under simple command

$ composer

Mac OS X

For Mac users it's suggested to install the Composer using Homebrew

$ brew install composer

It's possible, that you don't have installed PHP you system, so before installing Composer, you should install it by

$ brew tap homebrew/dupes
$ brew tap homebrew/versions
$ brew tap homebrew/homebrew-php
$ brew install php71

Now you should be able to run Composer command in console

$ composer

If for some reason, you cannot use Homebrew, or you don't want to, install the Composer like a Linux user would do.

Windows

It's suggested to use the installer, which you can get in the download section of Composer website.

Configuration

Composer is closely integrated with version control tool Git. If you do not use Git, it is necessary to tell it to Composer:

composer -g config preferred-install dist

Creating New Project

New Nette project can be created by executing a simple command

$ composer create-project nette/sandbox name-of-the-project

Instead the name-of-the-project you should provide appropriate name and execute the command. Composer will fetch the nette/sandbox repository from GitHub and, right after that, install the nette/nette package, which is Nette Framework itself. The only thing which remains is to check write permissions on directories temp/ and log/ and you're ready to go.

Packagist.org – Global Repository

Packagist is the main package repository, in which Composer tries to search packages, if not told otherwise. You can also publish your own packages here, just like Nette did.

The easiest way to publish a package is to upload it on GitHub using Git and to paste url of the resulting repository into Packagist. More detailed description about creating a new package is in following paragraphs.

Usage

The starting point for every project or library which uses Composer is composer.json file, which defines meta information and dependencies of your project.

The simplest composer.json can look like this:

{
    "require": {
        "php" : ">=5.6.1",
        "nette/nette": "~2.4.0"
    }
}

We're saying here, that our application (or library) depends on package nette/nette and it wants the newest version, that matches the ~2.4.0 version constraint and also that it will only run on PHP higher or equal to 5.6.1.

So, when we have the composer.json file in the project root and we run

$ composer update

Composer will download the Nette Framework, and will put it into directory vendor/nette/nette.

If you're using latest nette/sandbox, everything mentioned until here is already in place and you don't need to do it yourself.

Lock File

When you run composer update, Composer creates composer.lock file right next to composer.json. This file contains metadata about packages and versions which are really installed.

It's standard that we commit composer.lock file only into concrete applications and not into libraries. There can be a situation, when a newer version of some our dependency is released, and our colleague will pull the latest version of our application, calls the $ composer install and now he has newer version of that library. The lock file prevents this, because when you run the install and not update, the Composer will always install versions exactly as they are in the lock file.

If we want to update the dependencies to newer ones, it's simple as calling $ composer update.

What If We Don't Want the Central Repository

If we have internal applications or libraries in our company, which cannot be hosted publicly on GitHub and Packagist, we can create our own repositories for those project.

Nette Framework is always available publicly thanks to the central repository, but let's use it for demonstration purposes and assume we don't want to have it publicly available. You can put any path or address into url; it shall point to a git, mercurial or svn repository.

{
    "repositories": [
        {
            "type": "vcs",
            "url": "git://github.com/nette/nette.git"
        }
    ],
    "require": {
        "nette/nette": "dev-master",
    }
}

Composer can work also with Pear repositories (just specify the type) or zip files (distribution packages).

If you specify repositories, Composer will always need to fetch all branched during each install/update, which is unnecessarily time-consuming. Your company can have its own fork of packagist or its simpler and lightweight version. Nette community has developed a portal Componette for the aggregation all repositories.

More on repositories in the official documentation.

What If We Have Our Project Already Running?

Don't consider it a disadvantage, but a possibility of improving the whole project. Composer is not capable of installing only some dependencies – it has to take care of all of them.

The recommended way is to create a composer.json file, list all dependencies your project have, install them via Composer and then delete the old and manually downloaded libraries in libs/.

Our Own Packages

Any project, which has composer.json in its root, can work as a Composer package. If it needs to work as a dependency, it needs to have defined at least two fields: name and version.

{
    "name": "MyName/Blog",
    "description" : "The Super Cool Blog.com",
    "version": "1.0.0"
}

The name consists of a vendor name and concrete package name – it shall prevent conflicts.

If we use a Version Control System (e.g. git), it is not necessary to specify the version parameter. Composer can detect tags and branches from git and those one, which look like version numbers, can be automatically used as dependencies.

Autoloading

Composer solves the autoloading problem automatically so you don't need to focus on it anymore. Each library can provide in its composer.json the autoloading standard it uses and Composer will take care of it. If we use PSR-0, our top-most namespace is MyApp and the code is located in libs/ directory, then the autoloading part can look like:

{
    "autoload": {
        "psr-0": {"MyApp": "libs/"},
    }
}

But what if our codebase doesn't comply to PSR-0 standard? No problem. We can specify classmap instead of psr-0, which is an equivalent of Nette's RobotLoader.

{
    "autoload": {
        "classmap": ["src/", "lib/"]
    }
}

Composer will process autoloading sections from all libraries in the project, combine them and will create a single autoloader. All libraries, which specified autoloading, will now be autoloaded automatically.

Composer can also generate classmap via command composer dump-autoload -o.

How to Use Composer's Autoload

When we create a new project from sandbox, composer will download dependencies and prepare autoloading. But the default bootstrap.php ties to use RobotLoader on libs/, which shall be disabled by removing the following line:

->addDirectory(__DIR__ . '/../libs')  // remove this line from your bootstrap

Now, there should not be any conflicts in autoloading.