intermediate
Step 11 of 16
Composer and Dependency Management
PHP Programming
Composer and Dependency Management
Composer is the standard dependency manager for PHP, similar to npm for JavaScript or pip for Python. It handles package installation, version resolution, autoloading, and project configuration. Composer uses a composer.json file to define your project's dependencies and a composer.lock file to ensure reproducible installs across different environments. Understanding Composer is essential for modern PHP development — every major framework and library uses it, and it provides PSR-4 autoloading that eliminates the need for manual require statements.
Getting Started with Composer
# Install Composer (macOS)
brew install composer
# Or download from getcomposer.org
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
# Initialize a new project
composer init
# Install a package
composer require guzzlehttp/guzzle
composer require vlucas/phpdotenv
# Install dev-only packages
composer require --dev phpunit/phpunit
composer require --dev phpstan/phpstan
# Install from composer.json
composer install
# Update packages
composer update
composer.json Configuration
{
"name": "myapp/web-project",
"description": "A PHP web application",
"type": "project",
"require": {
"php": ">=8.1",
"guzzlehttp/guzzle": "^7.0",
"vlucas/phpdotenv": "^5.5",
"monolog/monolog": "^3.0"
},
"require-dev": {
"phpunit/phpunit": "^10.0",
"phpstan/phpstan": "^1.0"
},
"autoload": {
"psr-4": {
"App\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\": "tests/"
}
},
"scripts": {
"test": "phpunit",
"analyse": "phpstan analyse src",
"start": "php -S localhost:8000 -t public"
}
}
PSR-4 Autoloading
<?php
// src/Models/User.php
namespace App\Models;
class User {
public function __construct(
private readonly int $id,
private readonly string $name,
private readonly string $email
) {}
public function getName(): string { return $this->name; }
public function getEmail(): string { return $this->email; }
}
// src/Services/UserService.php
namespace App\Services;
use App\Models\User;
class UserService {
public function createUser(string $name, string $email): User {
return new User(0, $name, $email);
}
}
// public/index.php (entry point)
require_once __DIR__ . '/../vendor/autoload.php';
use App\Services\UserService;
use Dotenv\Dotenv;
// Load environment variables
$dotenv = Dotenv::createImmutable(__DIR__ . '/..');
$dotenv->load();
$service = new UserService();
$user = $service->createUser('Alice', 'alice@example.com');
echo $user->getName();
?>
Project Structure
# Standard PHP project layout
my-project/
├── composer.json
├── composer.lock
├── .env # Environment variables (never commit)
├── .gitignore
├── public/ # Web root (only this is accessible via web)
│ ├── index.php # Entry point
│ └── assets/
│ ├── css/
│ └── js/
├── src/ # Application code (PSR-4: App\)
│ ├── Controllers/
│ ├── Models/
│ ├── Services/
│ └── Middleware/
├── config/ # Configuration files
├── templates/ # View templates
├── tests/ # Test files (PSR-4: Tests\)
├── storage/ # Logs, cache, uploads
│ ├── logs/
│ └── cache/
└── vendor/ # Composer dependencies (never commit)
Pro tip: Always commitcomposer.lockto version control — it ensures every developer and server installs the exact same versions of dependencies. Usecomposer install(notcomposer update) in production and CI environments to get reproducible builds. Never commit thevendor/directory.
Key Takeaways
- Composer manages PHP dependencies with
composer.json(requirements) andcomposer.lock(exact versions). - PSR-4 autoloading maps namespaces to directories, eliminating manual
requirestatements. - Use
requirefor production dependencies andrequire --devfor development tools. - Always commit
composer.lockand never commitvendor/to version control. - Use Composer scripts for common tasks:
composer test,composer start, etc.