Use when composer package management and PSR-4 autoloading including dependency management, autoload strategies, package creation, version constraints, and patterns for modern PHP project organization and distribution.
Read-only skill
Additional assets for this skill
This skill cannot use any tools. It operates in read-only mode without the ability to modify files or execute commands.
Composer is PHP's de facto dependency manager, handling package installation, autoloading, and version management. PSR-4 autoloading eliminates manual require statements by automatically loading classes based on namespace and file structure conventions.
Composer revolutionized PHP development by providing standardized dependency management similar to npm, pip, or Maven. Combined with PSR-4 autoloading, Composer enables modern PHP projects to organize code cleanly, share packages easily, and manage dependencies reliably.
This skill covers Composer basics, dependency management, autoloading strategies, package creation, semantic versioning, and best practices for maintainable PHP projects.
Composer manages project dependencies through composer.json configuration and installs packages into the vendor directory.
{
"name": "company/project",
"description": "Project description",
"type": "project",
"require": {
"php": ">=8.1",
"symfony/console": "^6.0",
"guzzlehttp/guzzle": "^7.5",
"monolog/monolog": "^3.0"
},
"require-dev": {
"phpunit/phpunit": "^10.0",
"phpstan/phpstan": "^1.10",
"squizlabs/php_codesniffer": "^3.7"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"test": "phpunit",
"lint": "phpcs",
"analyse": "phpstan analyse"
},
"config": {
"optimize-autoloader": true,
"sort-packages": true
}
}
# Install dependencies
composer install
# Install specific package
composer require symfony/http-foundation
# Install development dependency
composer require --dev symfony/var-dumper
# Update dependencies
composer update
# Update specific package
composer update monolog/monolog
# Remove package
composer remove guzzlehttp/guzzle
# Show installed packages
composer show
# Show outdated packages
composer outdated
# Validate composer.json
composer validate
# Run script
composer test
Composer creates composer.lock to lock exact dependency versions, ensuring consistent installations across environments.
PSR-4 autoloading maps namespaces to directories, automatically loading classes without manual require statements.
<?php
// composer.json autoload configuration
{
"autoload": {
"psr-4": {
"App\\": "src/",
"App\\Controllers\\": "src/Controllers/",
"App\\Models\\": "src/Models/"
}
}
}
// Directory structure
// src/
// User.php
// Controllers/
// UserController.php
// Models/
// UserModel.php
// src/User.php
namespace App;
class User {
public function __construct(
public string $name,
public string $email
) {}
}
// src/Controllers/UserController.php
namespace App\Controllers;
use App\User;
use App\Models\UserModel;
class UserController {
public function show(int $id): User {
$model = new UserModel();
return $model->find($id);
}
}
// src/Models/UserModel.php
namespace App\Models;
use App\User;
class UserModel {
public function find(int $id): User {
return new User("Alice", "alice@example.com");
}
}
// index.php - Composer autoloader
require __DIR__ . '/vendor/autoload.php';
use App\Controllers\UserController;
$controller = new UserController();
$user = $controller->show(1);
echo $user->name; // "Alice"
<?php
// Multiple autoload strategies
{
"autoload": {
"psr-4": {
"App\\": "src/"
},
"classmap": [
"database/seeds",
"database/factories"
],
"files": [
"src/helpers.php"
]
}
}
// Regenerate autoloader after changes
// composer dump-autoload
// Optimize autoloader for production
// composer dump-autoload --optimize
// composer dump-autoload --classmap-authoritative
PSR-4 eliminates require statements and enables consistent project structure across PHP projects.
Semantic versioning and version constraints control which package versions Composer installs and updates.
{
"require": {
"vendor/package": "1.2.3",
"vendor/exact": "1.0.0",
"vendor/caret": "^2.0",
"vendor/tilde": "~3.1",
"vendor/wildcard": "4.*",
"vendor/range": ">=5.0 <6.0",
"vendor/latest": "dev-master",
"vendor/branch": "dev-feature-x",
"vendor/stability": "1.0@beta"
}
}
Version constraint patterns:
1.2.3 - Exact version^1.2.3 - Caret: >=1.2.3 <2.0.0 (compatible)~1.2.3 - Tilde: >=1.2.3 <1.3.0 (similar)1.* - Wildcard: >=1.0.0 <2.0.0>=1.0 <2.0 - Range: explicit min/maxdev-master - Development branch1.0@beta - Specific stability{
"require": {
"symfony/console": "^6.0",
"monolog/monolog": "^3.0",
"guzzlehttp/guzzle": "^7.5"
},
"minimum-stability": "stable",
"prefer-stable": true
}
# Show why package installed
composer why vendor/package
# Show what depends on package
composer depends vendor/package
# Show what package provides
composer show --all vendor/package
# Check for security vulnerabilities
composer audit
# Show platform requirements
composer check-platform-reqs
# Diagnose issues
composer diagnose
Semantic versioning (MAJOR.MINOR.PATCH) communicates breaking changes, features, and fixes in version numbers.
Creating reusable Composer packages enables code sharing across projects and with the community.
{
"name": "company/http-client",
"description": "HTTP client wrapper",
"type": "library",
"keywords": ["http", "client", "api"],
"license": "MIT",
"authors": [
{
"name": "Developer Name",
"email": "dev@example.com"
}
],
"require": {
"php": ">=8.1",
"guzzlehttp/guzzle": "^7.5"
},
"require-dev": {
"phpunit/phpunit": "^10.0"
},
"autoload": {
"psr-4": {
"Company\\HttpClient\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
}
}
<?php
// src/Client.php
namespace Company\HttpClient;
use GuzzleHttp\Client as GuzzleClient;
class Client {
private GuzzleClient $client;
public function __construct(string $baseUrl) {
$this->client = new GuzzleClient(['base_uri' => $baseUrl]);
}
public function get(string $path): array {
$response = $this->client->get($path);
return json_decode($response->getBody(), true);
}
public function post(string $path, array $data): array {
$response = $this->client->post($path, ['json' => $data]);
return json_decode($response->getBody(), true);
}
}
// tests/ClientTest.php
namespace Tests;
use Company\HttpClient\Client;
use PHPUnit\Framework\TestCase;
class ClientTest extends TestCase {
public function testCanCreateClient(): void {
$client = new Client('https://api.example.com');
$this->assertInstanceOf(Client::class, $client);
}
}
# Validate package
composer validate
# Initialize new package
composer init
# Publish to Packagist
# 1. Create GitHub repository
# 2. Push code with composer.json
# 3. Submit to packagist.org
# Private packages
# Add to composer.json:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/company/private-package"
}
]
}
Well-designed packages follow PSR standards, include tests, and provide clear documentation.
Optimizing autoloading improves production performance by reducing file system lookups.
# Generate optimized autoloader
composer dump-autoload --optimize
# Classmap authoritative (no file system checks)
composer dump-autoload --classmap-authoritative
# APCu cache (requires apcu extension)
composer dump-autoload --apcu
{
"config": {
"optimize-autoloader": true,
"classmap-authoritative": true,
"apcu-autoloader": true
}
}
<?php
// Autoload optimization levels
// 1. Default PSR-4 (checks file system)
// Slowest, flexible
// 2. Optimized (builds class map)
// Fast, checks file system if not in map
// 3. Authoritative (class map only)
// Fastest, no file system checks
// Use in production
// Measure impact
$start = microtime(true);
// Autoload many classes
for ($i = 0; $i < 1000; $i++) {
$class = "App\\Service$i";
if (class_exists($class)) {
// Use class
}
}
$duration = microtime(true) - $start;
echo "Duration: $duration seconds\n";
Authoritative classmap provides best performance but requires regeneration after code changes.
Composer scripts automate common development tasks and check platform requirements.
{
"scripts": {
"test": "phpunit",
"test:unit": "phpunit --testsuite=unit",
"test:integration": "phpunit --testsuite=integration",
"lint": "phpcs --standard=PSR12 src",
"lint:fix": "phpcbf --standard=PSR12 src",
"analyse": "phpstan analyse src --level=max",
"check": [
"@lint",
"@analyse",
"@test"
],
"post-install-cmd": [
"@php artisan key:generate --ansi"
],
"post-update-cmd": [
"@php artisan vendor:publish --tag=public --ansi"
]
},
"scripts-descriptions": {
"test": "Run all tests",
"lint": "Check code style",
"check": "Run all checks"
}
}
{
"require": {
"php": "^8.1",
"ext-pdo": "*",
"ext-mbstring": "*",
"ext-intl": "*"
},
"suggest": {
"ext-redis": "For Redis cache support",
"ext-imagick": "For image manipulation"
},
"platform": {
"php": "8.1.0"
},
"platform-check": true
}
# Run script
composer test
composer run-script test
# Run with arguments
composer test -- --filter=UserTest
# List scripts
composer run-script --list
# Check platform requirements
composer check-platform-reqs
Scripts enable CI/CD integration and consistent development workflows across team members.
Managing multiple related packages in a single repository using path repositories.
{
"name": "company/monorepo",
"repositories": [
{
"type": "path",
"url": "./packages/http-client"
},
{
"type": "path",
"url": "./packages/database"
},
{
"type": "path",
"url": "./packages/auth"
}
],
"require": {
"company/http-client": "@dev",
"company/database": "@dev",
"company/auth": "@dev"
}
}
monorepo/
├── composer.json
├── packages/
│ ├── http-client/
│ │ ├── composer.json
│ │ └── src/
│ ├── database/
│ │ ├── composer.json
│ │ └── src/
│ └── auth/
│ ├── composer.json
│ └── src/
└── vendor/
// packages/http-client/composer.json
{
"name": "company/http-client",
"autoload": {
"psr-4": {
"Company\\HttpClient\\": "src/"
}
}
}
// packages/auth/composer.json
{
"name": "company/auth",
"require": {
"company/http-client": "^1.0"
},
"autoload": {
"psr-4": {
"Company\\Auth\\": "src/"
}
}
}
Path repositories enable local development of interdependent packages without publishing.
Commit composer.lock to version control to ensure consistent dependency versions across environments
Use caret constraints for dependencies (^1.2.3) to allow compatible updates while preventing breaking changes
Separate runtime and development dependencies using require and require-dev for smaller production installs
Optimize autoloader for production with --classmap-authoritative to eliminate file system checks
Follow PSR-4 autoloading conventions with namespace-to-directory mapping for consistency
Specify minimum PHP version and extensions in require section to catch compatibility issues early
Use scripts for common tasks to standardize development workflows across team members
Keep dependencies updated by regularly running composer outdated and updating packages
Validate composer.json regularly with composer validate to catch configuration errors
Use semantic versioning for packages to communicate changes clearly and enable automatic updates
Not committing composer.lock causes different dependency versions across environments and unpredictable behavior
Using exact version constraints (1.2.3) prevents security updates and bug fixes from being installed
Running composer update blindly can introduce breaking changes; review updates before applying
Mixing PSR-4 with manual requires defeats autoloading purpose and creates maintenance burden
Not optimizing autoloader for production causes performance degradation from file system checks
Ignoring composer.json validation errors leads to installation failures and hard-to-debug issues
Not specifying PHP version requirements allows installation on incompatible PHP versions
Using global Composer for project-specific packages creates conflicts and version mismatches
Not using --no-dev flag in production installs unnecessary development dependencies
Forgetting to run dump-autoload after adding new classes causes class not found errors
Use Composer for any modern PHP project to manage dependencies, autoloading, and package distribution professionally.
Apply PSR-4 autoloading when organizing project code to eliminate manual require statements and follow industry standards.
Employ version constraints when managing dependencies to balance stability with security updates and bug fixes.
Create packages when building reusable functionality that could benefit multiple projects or the wider community.
Leverage Composer scripts for CI/CD pipelines, development workflows, and automated testing to ensure consistency.