How to use Composer - a PHP package manager
Composer is a tool for dependency management in PHP. It allows you to declare the libraries your project depends on and helps to manage those dependencies.
Dependencies are managed on a per-project basis, installing them in a directory inside your project. For convenience some dependencies can be installed globally (e.g., Symfony project installer).
Skip to any of the sections:
- How to install and update
- Adding dependencies
- Removing dependency
- Initializing composer.json file
- Updating the dependency
- Installing dependencies
- Autoloading
- Creating a project
- Loading custom package / replacing existing package
- Running Composer globally
- Adding platform requirements
- Speed up installation of dependencies
How to install and update
Composer can be installed by running:
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer
This will install Composer in the directory /usr/local/bin
(which should be in your path) allowing you to run it from anywhere by using composer
command.
If your installation is working correctly you should see the version and available commands:
composer
To make sure that you're using the latest version of Composer, constantly run the self update:
composer self-update
Installing on OS X
If you use OS X you can install Composer through Homebrew:
brew install homebrew/php/composer
Check the documentation if any of the installation options doesn't work for you (e.g., install locally or on Windows).
Adding dependencies
To add a dependency your project needs to use the require
command with a package name (format <vendor>/<name>
) command:
composer require monolog/monolog
# Signature:
composer require <vendor>/<name>
# Signature of adding multiple dependencies:
composer require <vendor>/<name> <vendor2>/<name> <vendor2>/<name2>
This creates the composer.json
file (if it doesn't exist), and installs the dependency (including dependencies your dependency depends on).
Avoid changing composer.json
file manually, most of the time the require
command is enough to manage dependencies.
To add a development dependency use the --dev
flag with require
command:
composer require --dev phpspec/phpspec
# Signature:
composer require --dev <vendor>/<name>
Adding specific version
The require
command will automatically choose a suitable version you can use in your project. If you need to provide the specific version of dependency provide it with the package name:
composer require monolog/monolog:~1.17.0
# Signature:
composer require <vendor>/<name>:<version>
Version to use can be defined in the following ways:
- The
^
(caret) operator means any non-breaking version / until major (e.g.,^1.2.3
is equivalent to>=1.2.3 <2.0.0
) - The
~
(tilde) operator means approximate / increment right most digit (e.g.,~1.2
is equivalent to>=1.2 <2.0.0
or~1.2.3
is equivalent to>=1.2.3 <1.3.0
) - Read the documentation to learn about other version constraints (exact, range, wildcard)
Versions are described using semantic versioning (SemVer) which uses the format MAJOR.MINOR.PATCH
. Each of the numbers have a specific meaning:
MAJOR
- API changes that break backwards-compatibilityMINOR
- new featuresPATCH
- bug fixes
Removing dependency
If you don't need the dependency anymore use the remove
command to remove it from the composer.json
file and directory:
composer remove monolog/monolog
# Signature:
composer remove <vendor>/<name>
To remove the development dependency add --dev
flag to remove
command:
composer remove --dev phpspec/phpspec
# Signature:
composer remove --dev <vendor>/<name>
Initializing composer.json file
If you are creating a package or want to fill a composer.json
file interactively, use the init
command:
composer init
This will ask you to provide information like package name, description, dependencies, etc. After you provide all the information it will generate a composer.json
file.
Updating the dependency
To get the latest versions of the dependencies (also updates the composer.lock
file) use the update
command:
composer update
If you want to update only specific packages provide them to the update
command:
composer update monolog/monolog
# Signature:
composer update <vendor>/<name>
# Wildcard is allowed to update multiple packages (without listing them):
composer update <vendor>/*
Installing dependencies
Use the install
command to install project dependencies:
composer install
This will read the composer.json
file and resolve your dependencies. After finishing the installation it will create a composer.lock
file, which contains the exact versions installed. This makes sure that the same versions are installed every time the install
command is executed.
Commit your application's composer.lock
file (along with composer.json
) into version control.
By convention dependencies are installed into a vendor
directory, which should not be committed to version control.
Installing dependencies on production servers
You will want to use a few flags when installing dependencies on production servers:
composer install --prefer-dist --no-dev --optimize-autoloader --no-interaction
This will optimize the dependency installation which is really useful for production servers. It will try to install distribution packages (--prefer-dist
flag), won't install development dependencies (--no-dev
flag), and generate a classmap for faster autoloader (--optimize-autoloader
flag). The --no-interaction
flag will make sure that no interactive questions are asked (needed for automated deployments).
Autoloading
Composer generates a vendor/autoload.php
file which automatically loads the classes your project depends on. Just include that file in your PHP script:
require __DIR__.'/vendor/autoload.php'
You can change the autoload
key in your composer.json
file to define the mapping.
If you added new classes you might need to update the autoloader. Use the dump-autoload
command to do that:
composer dump-autoload
# For production use
composer dump-autoload --optimize --no-dev
PSR-4
Under the psr-4
key you define a mapping from namespaces to paths, relative to the package root. The PSR-4 is the recommended choice for autoloading (avoids having to regenerate the autoloader after adding classes).
Namespace prefixes must end in \\
to avoid conflicts between similar prefixes.
In addition to normal mapping definition, you can define multiple directories, or define a fallback directory:
{
"autoload": {
"psr-4": {
"Vendor\\Namespace\\Normal\\": "src/",
"Vendor\\Namespace\\Multi\\": ["src/", "lib/"],
"": "src/fallback/"
}
}
}
PSR-0
Under the psr-0
key you define a mapping from namespaces to paths, relative to the package root. This also supports the PEAR-style non-namespaced convention.
Namespace prefixes should end in \\
to avoid conflicts between similar prefixes.
In addition to normal mapping definition, you can define multiple directories, or define a fallback directory:
{
"autoload": {
"psr-0": {
"Vendor\\Namespace\\Normal\\": "src/",
"Vendor_Namespace_PEAR_": "src/",
"Vendor\\Namespace\\Multi\\": ["src/", "lib/"],
"": "src/fallback/"
}
}
}
Classmap
For libraries that do not follow PSR-0/4 you can specify directories or files to search for classes (using the classmap
key):
{
"autoload": {
"classmap": ["src/", "lib/", "Something.php"]
}
}
Development autoloading
You should avoid polluting the autoloader in production with classes it doesn't need (like test suite). Using the autoload-dev
key you can define classes that should be loaded only in development:
{
"autoload-dev": {
"psr-4": {
"MyLibrary\\Tests\\": "tests/"
}
}
}
Creating a project
The create-project
command will create a new project from an existing package. It's the equivalent of doing a git clone followed by installation of dependencies. The command takes the package name and the directory to create it in (optional: provide the version as third parameter):
composer create-project symfony/framework-standard-edition my_project_name
# or
composer create-project symfony/framework-standard-edition my_project_name 3.1.*
# Signature:
composer create-project <vendor>/<name> <path> <optional:version>
Loading custom package / replacing existing package
In some cases you might want to use a custom package. For example you fixed a bug in open source library and while waiting for PR to be merged you want to use the fixed library.
The branch on the forked repository should be prefixed with dev-
(e.g., in the repository it will be bugfix
, in the composer.json
file it will be dev-bugfix
). Then change the repositories
key in composer.json
(in example assume that I forked Monolog
and created bugfix
branch):
{
"repositories": [
"type": "vcs",
"url": "https://github.com/ifdattic/monolog"
],
"require": {
"monolog/monolog": "dev-bugfix"
}
}
Now after updating the dependency it should replace the original package with a changed one (don't change the package name for override to work):
composer update monolog/monolog
# Signature
composer update
# or
composer update <vendor>/<name>
To avoid conflicts you might need to alias the branch for it to be treated as a specific version. To make in-line aliases use the as
keyword:
{
"require": {
"monolog/monolog": "dev-bugfix as 1.18.1"
}
}
Adding / removing repository through CLI
If you don't want to manually add repository use the composer config repositories
command:
composer config repositories.monolog vcs https://github.com/ifdattic/monolog
# Signature:
composer config repositories.<name> <type> <url>
To remove a repository use --unset
flag (repo
is alias for repositories
):
composer config --unset repo.monolog
# Signature:
composer config --unset repo.<name>
Running Composer globally
Sometimes you might want to install some CLI tools globally. Using global
command it will allow to install them to the directory defined in COMPOSER_HOME
environment variable:
composer global require fabpot/php-cs-fixer
# Signature:
composer global <command> <vendor>/<name>
Adding platform requirements
If you need to add requirements for the system you can use platform packages. They are virtual packages of the things that are installed on the system. For example the following snippet requires for PHP 7 to be available:
{
"require": {
"php": "^7.0"
}
}
The following platform packages are available: php
, hhvm
, ext-<name>
, lib-<name>
.
To get a list of locally available platform packages run:
composer show --platform
Speed up installation of dependencies
If your project has a lot of dependencies, it can take a long time for them to install. You can speed up the installation by installing dependencies in parallel.
To achieve this install prestissimo composer plugin:
composer global require hirak/prestissimo
It might not make a difference if you're updating a single dependency for your project (it might still use only a single connection). It does improve the speed when installing a lot of dependencies (like when starting a new project or deploying to production).
Conclusion
You can do a lot more with Composer, but this should take care of most of the use cases while developing.