Composer is the de-facto dependency manager for PHP;

This trend has rather strong implications for site builders, as once a site uses at least one module that uses Composer, then it becomes necessary to also use Composer to manage your site.

Note for drupalers

For Drupal developers is becoming more common for Drupal modules to use Composer to include the external libraries it needs to function.

Why is composer needed?

When you are dealing with your project’s dependencies by your own you are running into troubles:

How will I manage the class autoloading (without using include or require statements)?

How do I manage dependencies or dependencies? How should I store the libraries into my project: bundle them as they are into my repository? This will bloat your project and will create troubles versioning them since the libraries are part of other git repositories. (Should I then use git modules to solve that)? Briefly, a shortcut to run into troubles.

Composer comes to solve these intricate difficult problems.

Composer is not a package manager. It deals with “packages” or libraries, but it manages them on a per-project basis, installing them in a directory (e.g. vendor) inside your project. By default it will never install anything globally. Thus, it is a dependency manager.

Composer is strongly inspired by node’s npm and ruby’s Bundler. But there has not been such a tool for PHP.

Prerequisites

Install it. I recommend globally.

$ composer --version
Composer version 2.1.8 2021-09-15 13:55:14

You can upgrade composer with sudo composer self-update

All your dependecies live in the composer.json. Composer uses a composer.json file to specify settings and package requirements for your application.

composer.json

You can think of Composer as a shopping list. You simply define the wish list creating a file where you add the “require” keyword:

Instead of editing manually the file you can do it command line: composer require monolog/monolog:1.0.

{
    "require": {
        "monolog/monolog": "1.0.*"
    }
}

If require complains about privileges in a non-public space like /var/www/html/your-project for example use sudo chown -R :www-data /fullpath-to-your-project or wheel inseatd www-data on a non-Ubuntu system like RHEL.

Composer will then automatically update your composer.json

composer require 'drupal/token:^1.5'
composer require 'drupal/simple_fb_connect:~3.0'
composer require 'drupal/ctools:3.0.0-alpha26'
composer require 'drupal/token:1.x-dev'

To avoid problems on different terminals/shells, surround the version in quotes as in the examples above.

In these examples, the versions map as follows:

^1.5: maps to the latest stable 8.x-1.x release of the module. ~3.0: maps to the latest stable 8.x-3.x release of the module. 3.0.0-alpha26: maps to version 8.x-3.0-alpha26 1.x-dev: maps to 8.x-1.x-dev

This require maps package names to version constraints.

Edit composer.json interactivelly.

Instead editing the composer.json manually you can trigger composer init and have it in interactive mode: composer will ask you which libraries you want to include. At the prompt you simply add the package or library you need to include e.g finder or symfony/finder. Composer will figure out by looking to a huge repository called PHP Package Repository: packagist.org, which you can also search manually.

$ composer init

                                            
  Welcome to the Composer config generator  
                                            


This command will guide you through creating your composer.json config.

Package name (<vendor>/<name>) [larry/example.eu]: drupal/backup_migrate
Description []: 
Author [jazio <jazio@no-domain.no>, n to skip]: n
Minimum Stability []: n
Invalid minimum stability "n". Must be empty or one of: stable, RC, beta, alpha, dev
Minimum Stability []: stable
Package Type (e.g. library, project, metapackage, composer-plugin) []: project
License []: 

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]? yes
Search for a package: backup_migrate

Found 8 packages matching backup_migrate

   [0] inpsyde/search-and-replace 
   [1] mdespeuilles/backupmigratebundle 
   [2] chenhakim/migrate-backup 
   [3] pangolinkeys/backup-migrations 
   [4] fotobank/backup-migrations 
   [5] sebwas/laravel-migration-physical-backup Abandoned. No replacement was suggested.
   [6] anonym-php/anonym-database-tools 
   [7] chrisplugs/database-manage 


Install your libraries

Your libraries or dependencies can be installed via the following command:

$ composer install

You’ll now notice files being downloaded and placed into a new vendors/ folder within the root of your application. This vendor folder contains everything described in composer.json. It should never be committed into a git repository but instead, excluded via .gitignore

Post install scripts

You can make a more complex example: declare another github project (let’s say toolkit), map to the desired version.

Then run post install scripts prefixed by @.

{
    "name": "myproject/subsite",
    "require": {
        "myproject/toolkit": "3.*"
    },
    "scripts": {
        "post-install-cmd": "@toolkit-install",
        "post-update-cmd": "@toolkit-install",
        "toolkit-install": "PROJECT=$(pwd) composer run-script toolkit-install -d ./vendor/ec-europa/toolkit"
    }
}

Bonus feature: class autoloader

Composer bundles with a PSR-0 autoloader, which you can include in your project with only a single line: If you run composer global install, it will install it globally.

include_once './vendor/autoload.php';

You can use Composer to create new projects from an existing package. This is the equivalent of doing a git clone followed by a composer install of the vendors. Useful as installer when deploying application packages.

Practical Example: Install Drush via composer

Drush can be installed as project dependencies via Composer. This allow you to install Drush on a per-project basis, to ensure the proper version of is used. This is especially useful when using Drush in a build script run through a CI server such a Jenkins.

But you also can install Drush as global using global subcommand:

Here are various alternatives:

composer global require drush/drush
composer global require drush/drush:8.x-dev --prefer-source

After running composer install Drush will be available in the bin directory in your project dir. In order to use it from you shell, you need to add your the bin directory to your path and set the DRUSH_PHP environment variable. This can be done running the following commands from you project directory.

export PATH=`pwd`/bin:$PATH;
export DRUSH_PHP=`dirname $(which drush)`/composer-php;

Install multiple packages globally

You can’t install multiple versions of the same package. If you want to install all Drush versions (e.g 6 and 7) you cannot install them globally The files are installed in ~/.composer/vendor/ there you

vendor/{vendor}/{product}/{version}/

and in require

"vendor/product": ["version","version"...]

Update composer to version 2

composer self-update --2

References Composer Documentation

Switching Between Drush Major Versions

Install Alternative Drush Versions