Composer
What Is Composer?
In simple terms: Composer is PHP's package manager. Instead of downloading libraries by hand — a date library, a mailer, a PDF generator — you list them in a file, and Composer downloads them, together with everything they depend on, in compatible versions. It also generates an autoloader, so you can use all installed classes without writing require statements.
Technically: Composer is a dependency manager written in PHP. A project describes its requirements in composer.json; Composer resolves compatible versions (mostly from Packagist, the public package repository), installs them into vendor/, records the exact installed versions in composer.lock, and generates vendor/autoload.php (see Autoloading Classes and PSR-4 Autoloading). Practically every modern PHP project and framework uses Composer.
Installing Composer
Follow the instructions on https://getcomposer.org/download/, which verify the installer's checksum. On most systems, Composer is then available globally:
composer --version
Composer version 2.8.x
Starting a Project and Adding a Package
mkdir delivery-estimator && cd delivery-estimator
composer init --name=gocourse/delivery-estimator --type=project --no-interaction
composer require nesbot/carbon
composer require adds the package to composer.json, resolves its dependencies, downloads everything into vendor/, and writes composer.lock.
Using the Package
<?php
// estimate.php
require __DIR__ . '/vendor/autoload.php';
use Carbon\CarbonImmutable;
$ordered = CarbonImmutable::create(2026, 10, 15); // a Thursday
$delivery = $ordered->addWeekdays(3);
echo "Ordered: " . $ordered->format('l, d M Y') . "\n";
echo "Delivery: " . $delivery->format('l, d M Y') . "\n";
php estimate.php
Output
Ordered: Thursday, 15 Oct 2026
Delivery: Tuesday, 20 Oct 2026
How It Works
vendor/autoload.phpregisters Composer's autoloader for every installed package.Carbon\CarbonImmutable(an extension ofDateTimeImmutable) is loaded automatically on first use.addWeekdays(3)skips the weekend: Friday, Monday, Tuesday.
The Project Files
composer.json — What You Want
{
"name": "gocourse/delivery-estimator",
"type": "project",
"require": {
"php": "^8.3",
"ext-pdo": "*",
"nesbot/carbon": "^3.0"
},
"require-dev": {
"phpunit/phpunit": "^11.0"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"scripts": {
"test": "phpunit",
"lint": "find src -name '*.php' -print0 | xargs -0 -n1 php -l"
},
"config": {
"sort-packages": true
}
}
| Key | Purpose |
|---|---|
require | Packages needed in production, plus the required PHP version and extensions (php, ext-pdo) |
require-dev | Packages needed only for development (tests, static analysis) |
autoload | How your own classes are loaded (PSR-4 mapping) |
scripts | Named commands: composer test, composer lint |
config | Composer settings |
composer.lock — What You Got
The lock file records the exact version (and source commit) of every installed package, including indirect dependencies. Everyone who runs composer install gets precisely the same versions.
vendor/ — The Installed Code
Generated by Composer. It is not committed to version control (add /vendor/ to .gitignore) and must never be edited by hand — changes would be lost on the next install.
| File / Folder | Commit to Git? |
|---|---|
composer.json | Yes |
composer.lock | Yes — for applications, so every environment uses identical versions |
vendor/ | No |
Version Constraints
| Constraint | Allows | Meaning |
|---|---|---|
^3.0 | >=3.0.0 <4.0.0 | Compatible updates (recommended; follows semantic versioning) |
^1.2.3 | >=1.2.3 <2.0.0 | At least 1.2.3, no new major version |
~1.2 | >=1.2 <2.0 | Like ^ for this case |
~1.2.3 | >=1.2.3 <1.3.0 | Patch updates only |
1.2.* | >=1.2.0 <1.3.0 | Any 1.2 version |
2.5.1 | Exactly 2.5.1 | Pinned (rarely needed; blocks security fixes) |
* | Anything | Avoid |
Under semantic versioning, a major version (3 → 4) may break compatibility, minor versions add features, and patch versions fix bugs. The caret (^) accepts minor and patch updates but not breaking changes.
Essential Commands
| Command | What It Does | When |
|---|---|---|
composer install | Installs exactly the versions in composer.lock | After cloning, in CI, on deployment |
composer require vendor/package | Adds a package | Adding a dependency |
composer require --dev vendor/package | Adds a development-only package | Test and analysis tools |
composer update | Updates packages within constraints and rewrites the lock file | Deliberately, followed by testing |
composer update vendor/package | Updates one package (and what it needs) | Targeted updates |
composer remove vendor/package | Removes a package | Cleaning up |
composer outdated --direct | Lists available newer versions | Planning updates |
composer audit | Reports installed packages with known security vulnerabilities | Regularly and in CI |
composer dump-autoload | Regenerates the autoloader | After changing autoload settings |
composer validate | Checks composer.json | Before committing changes |
install vs update
composer installreads the lock file — reproducible and safe for servers.composer updatechanges the lock file — run it on a development machine, test the results, and commit the new lock file.
Never run composer update on a production server.
Deploying With Composer
composer install --no-dev --optimize-autoloader --classmap-authoritative --no-interaction
| Option | Effect |
|---|---|
--no-dev | Skips development packages (test tools do not belong on production servers) |
--optimize-autoloader (-o) | Builds a class map for faster autoloading |
--classmap-authoritative | Loads classes only from the class map — fastest, and no filesystem lookups |
--no-interaction | Never waits for input (essential in scripts) |
Run composer audit in your deployment pipeline and fail the build if vulnerable packages are found.
Choosing Packages Wisely
Every dependency adds code you must trust and maintain. Before adding a package, check:
- Maintenance: recent releases, responses to issues, supported PHP versions.
- Popularity and quality: downloads on Packagist, tests, documentation.
- License: compatible with your project (MIT, BSD, and Apache-2.0 are common).
- Size of the dependency tree: a small helper should not pull in dozens of packages.
Popular, well-maintained examples include monolog/monolog (logging), symfony/mailer (email), guzzlehttp/guzzle (HTTP), vlucas/phpdotenv (environment files), nesbot/carbon (dates), and phpunit/phpunit (testing).
Common Mistakes
Committing vendor/
Effect: Huge repositories and merge conflicts.
Fix: Commit composer.json and composer.lock; run composer install.
Not Committing composer.lock for Applications
Effect: Servers install different versions than those tested.
Fix: Commit the lock file.
Running composer update in Production
Effect: Untested versions go live.
Fix: Update in development, test, commit the lock file, then composer install on servers.
Editing Files in vendor/
Effect: Changes disappear on the next install.
Fix: Extend or configure packages; contribute fixes upstream or use patches deliberately.
Ignoring Security Advisories
Effect: Known vulnerabilities remain in production.
Fix: Run composer audit regularly and update affected packages.
Best Practices
- Manage all third-party code with Composer and load it through
vendor/autoload.php. - Use caret constraints, commit
composer.lock, and never commitvendor/. - Declare the PHP version and required extensions in
require. - Deploy with
composer install --no-dev --optimize-autoloaderand audit dependencies regularly. - Keep dependencies few, maintained, and up to date.
Official reference: https://www.php.net/manual/en/install.composer.intro.php