Composer, Autoloading, and Project Structure
Composer is not only a package installer. It defines autoloading, scripts, platform requirements, and a repeatable dependency graph for the application.
A Practical composer.json
{
"name": "example/customer-portal",
"description": "Customer portal application",
"type": "project",
"require": {
"php": "^8.4",
"ext-json": "*",
"ext-pdo": "*",
"vlucas/phpdotenv": "^5.6"
},
"require-dev": {
"phpunit/phpunit": "^11.0"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"test": "phpunit",
"lint": "php -l public/index.php"
},
"config": {
"sort-packages": true
}
}
Set the PHP constraint to the supported version range for the environment you actually deploy. The example is a project policy, not a statement that every host runs that version.
Install and Update Mean Different Things
| Command | Use |
|---|---|
composer install | Install the exact dependency versions recorded in composer.lock. Use this in deployment. |
composer update | Resolve new versions allowed by composer.json and rewrite the lock file. Use intentionally during maintenance. |
composer audit | Check installed dependency versions against known security advisories. |
composer dump-autoload -o | Generate an optimized autoloader for production. |
Keep the Document Root Small
customer-portal/ ├── app/ ├── config/ ├── migrations/ ├── public/ │ ├── index.php │ └── assets/ ├── storage/ ├── templates/ ├── tests/ ├── vendor/ ├── .env ├── composer.json └── composer.lock
Configure the virtual host document root as customer-portal/public. That prevents accidental access to .env, logs, source code, and dependencies.
Bootstrap Once
<?php
declare(strict_types=1);
use Dotenv\Dotenv;
require dirname(__DIR__) . '/vendor/autoload.php';
$dotenv = Dotenv::createImmutable(dirname(__DIR__));
$dotenv->safeLoad();
set_exception_handler(static function (Throwable $exception): void {
error_log((string) $exception);
http_response_code(500);
echo 'The application encountered an error.';
});
Dependency Rules
- Commit
composer.jsonandcomposer.lockfor applications. - Do not commit
vendor/unless the deployment environment genuinely requires it. - Review package ownership, maintenance, release history, and transitive dependencies before adoption.
- Keep production dependencies separate from development tools.
- Run security audits and tests before merging dependency updates.