Composer Usage Tips
Composer is a tool for dependency management in PHP. It allows you to declare the libraries your project depends on and it will install and update them for you. We will learn:
- how to install Composer
- how to use it in a new or existing project
Installation
Composer is an executable .phar
file that you download and install as follows.
Windows
Use the official installer Composer-Setup.exe.
Linux, macOS
All you need is 4 commands, which you can copy from this page.
Furthermore, by copying it into a folder that is in the system's PATH
, Composer becomes globally accessible:
$ mv ./composer.phar ~/bin/composer # or /usr/local/bin/composer
Use in Project
To start using Composer in your project, all you need is a composer.json
file. This file describes the
dependencies of your project and may also contain other metadata. The simplest composer.json
can look like this:
{
"require": {
"nette/database": "^3.0"
}
}
We're saying here that our application (or library) requires the package nette/database
(the package name consists
of a vendor name and the project's name) and it wants a version that matches the ^3.0
version constraint (i.e., the
latest version 3).
So, with the composer.json
file in the project root, run:
composer update
Composer will download Nette Database into the vendor/
directory. It also creates a composer.lock
file, which contains information about exactly which library versions it installed.
Composer generates a vendor/autoload.php
file. You can simply include this file and start using the libraries'
classes without any extra work:
require __DIR__ . '/vendor/autoload.php';
$db = new Nette\Database\Connection('sqlite::memory:');
Update Packages to the Latest Versions
To update the used libraries to the latest versions according to the constraints defined in composer.json
, use the
composer update
command. For example, with the dependency "nette/database": "^3.0"
, it will install the
latest 3.x.x version, but not version 4.
To update the constraints in the composer.json
file, for example to "nette/database": "^4.1"
,
allowing the installation of the latest version, use the composer require nette/database
command.
To update all used Nette packages, you would need to list them all on the command line, e.g.:
composer require nette/application nette/forms latte/latte tracy/tracy ...
This is impractical. Therefore, use the simple script Composer Frontline that will do it for you:
php composer-frontline.php
Creating New Project
You can create a new Nette project using a single command:
composer create-project nette/web-project name-of-the-project
Replace name-of-the-project
with the directory name for your project and execute the command. Composer will
download the nette/web-project
repository from GitHub, which already contains a composer.json
file, and
then install the Nette Framework itself. All that remains is to set directory permissions for the
temp/
and log/
directories, and the project should be live.
If you know which PHP version your project will be hosted on, be sure to set it.
PHP Version
Composer always installs package versions compatible with the PHP version you are currently using (specifically, the PHP
version used on the command line when running Composer). This might not be the same version your web host uses. Therefore,
it's crucial to add information about the PHP version on your hosting to the composer.json
file. Then, only package
versions compatible with the host will be installed.
For example, to specify that the project will run on PHP 8.2.3, use the command:
composer config platform.php 8.2.3
The version will be written to the composer.json
file like this:
{
"config": {
"platform": {
"php": "8.2.3"
}
}
}
However, the PHP version number is also specified elsewhere in the file, in the require
section. While the first
number determines the version for which packages are installed, the second number indicates the version the application itself is
written for. For example, PhpStorm uses this to set the PHP language level. (Of course, it doesn't make sense for these
versions to differ, so the double entry is an oversight.) Set this version using the command:
composer require php 8.2.3 --no-update
Or directly in the composer.json
file:
{
"require": {
"php": "8.2.3"
}
}
Ignoring PHP Version
Packages typically specify both the lowest PHP version they are compatible with and the highest version they have been tested
against. If you intend to use an even newer PHP version, perhaps for testing, Composer will refuse to install such a package. The
solution is the --ignore-platform-req=php+
option, which makes Composer ignore the upper limits of the required PHP
version.
False Reports
When upgrading packages or changing version numbers, conflicts sometimes occur. One package has requirements that conflict with
another, and so on. However, Composer sometimes outputs false reports. It reports a conflict that doesn't actually exist. In such
cases, deleting the composer.lock
file and trying again can help.
If the error message persists, it is genuine, and you need to read it to understand what to modify and how.
Packagist.org – Global Repository
Packagist is the main repository where Composer searches for packages by default. You can also publish your own packages here.
What If We Don’t Want the Central Repository
If we have internal applications or libraries within our company that cannot be hosted publicly, we can create our own repositories for them.
Read more about repositories in the official documentation.
Autoloading
A key feature of Composer is that it provides autoloading for all the classes it installs. You activate this by including the
vendor/autoload.php
file.
However, you can also use Composer to load other classes from outside the vendor/
directory. The first option is
to let Composer scan defined directories and subdirectories, find all classes, and include them in the autoloader. To achieve
this, set autoload > classmap
in composer.json
:
{
"autoload": {
"classmap": [
"src/", # includes the src/ directory and its subdirectories
]
}
}
Subsequently, you need to run the composer dumpautoload
command after each change to regenerate the autoloading
tables. This is extremely inconvenient. It's much better to entrust this task to RobotLoader, which performs the same activity automatically in the background and
much faster.
The second option is to adhere to PSR-4. Simply put, it's a system where
namespaces and class names correspond to the directory structure and file names, e.g., App\Core\RouterFactory
will be
located in the file /path/to/App/Core/RouterFactory.php
. Configuration example:
{
"autoload": {
"psr-4": {
"App\\": "app/" # the App\ namespace is in the app/ directory
}
}
}
See the Composer documentation for details on how to configure this behavior.
Testing New Versions
Want to test a new development version of a package? Here's how. First, add this pair of options to your
composer.json
file. This allows installing development versions, but Composer will only resort to them if no stable
version combination satisfies the requirements:
{
"minimum-stability": "dev",
"prefer-stable": true,
}
We also recommend deleting the composer.lock
file, as Composer sometimes inexplicably refuses installation, and
this can resolve the issue.
Let's say the package is nette/utils
and the new version is 4.0. Install it using the command:
composer require nette/utils:4.0.x-dev
Or you can install a specific version, for example, 4.0.0-RC2:
composer require nette/utils:4.0.0-RC2
However, if another package depends on the library and is locked to an older version (e.g., ^3.1
), the ideal
solution is to update that dependent package to work with the new version. But if you just want to bypass the restriction and
force Composer to install the development version while pretending it's an older version (e.g., 3.1.6), you can use the
as
keyword:
composer require nette/utils "4.0.x-dev as 3.1.6"
Calling Commands
You can call your own predefined commands and scripts via Composer as if they were native Composer commands. For scripts
located in the vendor/bin
directory, you don't need to specify this path.
As an example, let's define a script in composer.json
that uses Nette
Tester to run tests:
{
"scripts": {
"tester": "tester tests -s"
}
}
We then run the tests using composer tester
. You can call the command even if you are not in the project's root
directory, but in one of its subdirectories.
Send Thanks
We'll show you a trick to please open source authors. You can easily give stars on GitHub to the libraries your project uses.
Simply install the symfony/thanks
library:
composer global require symfony/thanks
And then run:
composer thanks
Try it!
Configuration
Composer is closely integrated with the version control tool Git. If you don't have Git installed, you need to tell Composer not to use it:
composer -g config preferred-install dist