Composer autoloading — PSR-4, classmap, files
Intermediate5 min read·php-12-003
psr
Concept
Composer uses semantic versioning (SemVer) constraints to specify which package versions are acceptable. SemVer is MAJOR.MINOR.PATCH: MAJOR = breaking changes, MINOR = new backwards-compatible features, PATCH = backwards-compatible bug fixes.
Constraint operators:
^1.2.3(caret — most common): Allows>=1.2.3 <2.0.0. Permits minor and patch updates but not breaking changes. The leading non-zero digit is locked.^0.3.0means>=0.3.0 <0.4.0(minor is breaking when major is 0).~1.2.3(tilde): Allows>=1.2.3 <1.3.0. Only patch updates. More conservative than caret.>=1.2.0 <2.0.0: Explicit range. Equivalent to^1.2.0.1.2.*or1.*: Wildcard — any patch version, or any minor+patch.1.2.3: Exact version. Rarely the right choice — prevents bug-fix updates.dev-main: Install from a VCS branch (not a release). Unstable.
composer.lock: When you run composer install or composer update, Composer resolves constraints and writes exact versions (e.g., 1.2.7) to composer.lock. Future composer install always installs the locked versions. This is how you get reproducible builds — the constraint says what's allowed, the lock says what's installed.
Stability flags: ^1.0@beta — allow beta versions of this package. ^1.0@RC — allow release candidates.
Code Example
json
{
"require": {
"php": "^8.2",
"laravel/framework": "^11.0",
// Installs >=11.0.0, <12.0.0
// Will update to 11.1.0, 11.2.0, etc. on composer update
// Will NOT update to 12.0.0
"guzzlehttp/guzzle": "~7.4",
// Installs >=7.4.0, <7.5.0 — only patch updates
"some/exact-library": "3.0.1",
// Exact version — not updated even for patches (avoid this)
"ramsey/uuid": ">=4.0.0 <5.0.0",
// Same as ^4.0.0 but explicit
"some/new-thing": "1.*",
// Any 1.x version — equivalent to ^1.0 in most cases
"another/package": "dev-main",
// Install from 'main' branch — unstable, for development
}
}bash
# After changing constraints, resolve and update lock
composer update laravel/framework # update only this package
composer update # update all within constraints
composer update --with-all-dependencies # update with ALL dependencies
# Show what update would change without applying
composer update --dry-run
# Install from lock (what CI/CD should use)
composer install --no-dev --optimize-autoloader
# --no-dev: skip require-dev (production deployment)
# --optimize-autoloader: generate classmap for faster autoloading
# Check current vs latest available
composer outdated
composer outdated --direct # only direct dependencies