psr-autoloading-knowledge
PSR-4 Autoloading Knowledge
Quick Reference
| Concept | Description |
|---|---|
| Namespace Prefix | Maps to a base directory |
| FQCN | Fully Qualified Class Name |
| Path Mapping | Namespace → Directory → File |
Core Concept
PSR-4 defines how to autoload classes from file paths based on their fully qualified class name.
Namespace Prefix → Base Directory
Acme\Log\ → ./src/
FQCN → File Path
Acme\Log\Writer\FileWriter → ./src/Writer/FileWriter.php
Namespace to Path Mapping
The Formula
File Path = Base Directory + (FQCN - Namespace Prefix) + .php
Where:
- Namespace separators (\) → Directory separators (/)
- Class name → File name with .php extension
Examples
| FQCN | Namespace Prefix | Base Directory | File Path |
|---|---|---|---|
App\Entity\User |
App\ |
src/ |
src/Entity/User.php |
App\Domain\User\Entity\User |
App\ |
src/ |
src/Domain/User/Entity/User.php |
Vendor\Package\SubNs\ClassName |
Vendor\Package\ |
lib/ |
lib/SubNs/ClassName.php |
Composer Configuration
Basic Setup
{
"autoload": {
"psr-4": {
"App\\": "src/",
"App\\Tests\\": "tests/"
}
}
}
Multiple Directories
{
"autoload": {
"psr-4": {
"App\\": ["src/", "lib/"]
}
}
}
DDD Project Structure
{
"autoload": {
"psr-4": {
"App\\": "src/",
"App\\Domain\\": "src/Domain/",
"App\\Application\\": "src/Application/",
"App\\Infrastructure\\": "src/Infrastructure/",
"App\\Presentation\\": "src/Presentation/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
}
}
Symfony Bundle Structure
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Laravel Package Structure
{
"autoload": {
"psr-4": {
"Vendor\\Package\\": "src/"
}
}
}
Directory Structure Examples
Standard DDD Layout
project/
├── composer.json
├── src/
│ ├── Domain/
│ │ └── User/
│ │ ├── Entity/
│ │ │ └── User.php # App\Domain\User\Entity\User
│ │ ├── ValueObject/
│ │ │ └── Email.php # App\Domain\User\ValueObject\Email
│ │ ├── Repository/
│ │ │ └── UserRepositoryInterface.php
│ │ └── Event/
│ │ └── UserCreated.php
│ ├── Application/
│ │ └── User/
│ │ ├── Command/
│ │ │ └── CreateUserCommand.php
│ │ └── Handler/
│ │ └── CreateUserHandler.php
│ ├── Infrastructure/
│ │ └── Persistence/
│ │ └── Doctrine/
│ │ └── UserRepository.php
│ └── Presentation/
│ └── Api/
│ └── Controller/
│ └── UserController.php
└── tests/
└── Unit/
└── Domain/
└── User/
└── Entity/
└── UserTest.php # App\Tests\Unit\Domain\User\Entity\UserTest
Class Examples
// src/Domain/User/Entity/User.php
<?php
declare(strict_types=1);
namespace App\Domain\User\Entity;
use App\Domain\User\ValueObject\Email;
use App\Domain\User\ValueObject\UserId;
final class User
{
// ...
}
// src/Domain/User/ValueObject/Email.php
<?php
declare(strict_types=1);
namespace App\Domain\User\ValueObject;
final readonly class Email
{
// ...
}
Detection Patterns
Find Mismatched Namespaces
# Extract namespace from files and compare with path
for file in $(find src -name "*.php"); do
namespace=$(grep -m1 "^namespace" "$file" | sed 's/namespace //;s/;//')
expected_ns="App\\$(dirname ${file#src/} | tr '/' '\\')"
if [ "$namespace" != "$expected_ns" ]; then
echo "Mismatch: $file"
echo " Found: $namespace"
echo " Expected: $expected_ns"
fi
done
Find Classes Without Namespace
# Files with class but no namespace
grep -rL "^namespace" --include="*.php" src/ | \
xargs grep -l "^class\|^interface\|^trait\|^enum"
Find Incorrect Class Names
# Class name doesn't match filename
for file in $(find src -name "*.php"); do
filename=$(basename "$file" .php)
if ! grep -q "^\(class\|interface\|trait\|enum\) $filename" "$file"; then
echo "Mismatch: $file (expected class/interface/trait/enum $filename)"
fi
done
Validate Composer Autoload
# Dump autoload and check for errors
composer dump-autoload --strict 2>&1 | grep -i "warning\|error"
# Validate composer.json
composer validate --strict
Common Mistakes
1. Namespace vs Path Mismatch
// File: src/Domain/User/Entity/User.php
// BAD: Namespace doesn't match path
namespace App\User\Entity; // Missing "Domain"
// GOOD: Namespace matches path
namespace App\Domain\User\Entity;
2. Class Name vs Filename Mismatch
// File: src/Domain/UserEntity.php
// BAD: Class name doesn't match filename
class User { }
// GOOD: Class name matches filename
class UserEntity { }
3. Case Sensitivity Issues
// File: src/Domain/User/Entity/user.php (lowercase)
// BAD: Will fail on case-sensitive filesystems (Linux)
namespace App\Domain\User\Entity;
class User { }
// GOOD: Filename should be User.php (PascalCase)
4. Missing Trailing Backslash
// BAD: Missing trailing backslash
{
"autoload": {
"psr-4": {
"App": "src/"
}
}
}
// GOOD: Include trailing backslash
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
5. Incorrect Directory Separator
// BAD: Using backslash in path (Windows-only)
{
"autoload": {
"psr-4": {
"App\\": "src\\"
}
}
}
// GOOD: Use forward slash (cross-platform)
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
Verification Commands
# Regenerate autoload files
composer dump-autoload
# Optimize autoload (production)
composer dump-autoload --optimize
# Validate and show issues
composer dump-autoload --strict
# Test class loading
php -r "require 'vendor/autoload.php'; new App\Domain\User\Entity\User();"
PHP-CS-Fixer Rules
<?php
return (new PhpCsFixer\Config())
->setRules([
// PSR-4 related rules
'single_class_element_per_statement' => true,
'single_import_per_statement' => true,
'ordered_imports' => [
'sort_algorithm' => 'alpha',
],
'no_unused_imports' => true,
'fully_qualified_strict_types' => true,
]);
Integration with DDD Layers
Layer Mapping
| Layer | Namespace | Directory |
|---|---|---|
| Domain | App\Domain\{Context}\ |
src/Domain/{Context}/ |
| Application | App\Application\{Context}\ |
src/Application/{Context}/ |
| Infrastructure | App\Infrastructure\ |
src/Infrastructure/ |
| Presentation | App\Presentation\ |
src/Presentation/ |
Component Mapping
| Component | Namespace Pattern | Directory Pattern |
|---|---|---|
| Entity | App\Domain\{Context}\Entity\ |
src/Domain/{Context}/Entity/ |
| Value Object | App\Domain\{Context}\ValueObject\ |
src/Domain/{Context}/ValueObject/ |
| Repository | App\Domain\{Context}\Repository\ |
src/Domain/{Context}/Repository/ |
| Service | App\Domain\{Context}\Service\ |
src/Domain/{Context}/Service/ |
| Command | App\Application\{Context}\Command\ |
src/Application/{Context}/Command/ |
| Query | App\Application\{Context}\Query\ |
src/Application/{Context}/Query/ |
| Handler | App\Application\{Context}\Handler\ |
src/Application/{Context}/Handler/ |
See Also
references/psr-4-standard.md- Full PSR-4 specificationreferences/composer-integration.md- Composer autoload configurationreferences/directory-structure.md- Project structure examplesreferences/antipatterns.md- Common mistakes and fixesassets/report-template.md- Audit report template
More from dykyi-roman/awesome-claude-code
psr-overview-knowledge
PHP Standards Recommendations (PSR) overview knowledge base. Provides comprehensive reference for all accepted PSRs including PSR-1,3,4,6,7,11,12,13,14,15,16,17,18,20. Use for PSR selection decisions and compliance audits.
22detect-code-smells
Detects code smells in PHP codebases. Identifies God Class, Feature Envy, Data Clumps, Long Parameter List, Long Method, Primitive Obsession, Message Chains, Inappropriate Intimacy. Generates actionable reports with refactoring recommendations.
15clean-arch-knowledge
Clean Architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Clean Architecture and Hexagonal Architecture audits.
15ddd-knowledge
DDD architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Domain-Driven Design audits.
14testing-knowledge
Testing knowledge base for PHP 8.4 projects. Provides testing pyramid, AAA pattern, naming conventions, isolation principles, DDD testing guidelines, and PHPUnit patterns.
12bug-root-cause-finder
Root cause analysis methods for PHP bugs. Provides 5 Whys technique, fault tree analysis, git bisect guidance, and stack trace parsing.
12