An autoloader finds a class file when PHP first needs that class. PSR-4 provides a standard mapping between namespace names and directories, and Composer generates an autoloader from your configuration. This removes a long list of manual require statements without hiding where files belong. PHP-FIG also publishes other PSR standards for coding style and shared interfaces; those solve different problems. This reference focuses on PSR-4, case-sensitive paths, development namespaces, and useful interoperability boundaries. You will map App\Catalog\Product to a file and diagnose a class that works on one operating system but fails on another.
Understand the namespace-prefix mapping
A Composer psr-4 entry such as "App\\": "src/" says the App namespace prefix corresponds to src. The remaining namespace segments become directories, and the final class name becomes the filename. App\Catalog\Product therefore maps to src/Catalog/Product.php. The namespace declaration inside that file should be App\Catalog, and the declared class should be Product. The mapping is a lookup rule, not a command to create directories automatically. A use statement gives a local alias for a class name; it does not itself load every file in a directory. PHP asks registered autoloaders when an unknown class is referenced. Keep a consistent project layout so humans can follow the same mapping.
Preserve exact case across names and paths
PSR-4 expects case-sensitive matching of namespace segments and filenames. Windows or some macOS filesystems may permit a wrong-case path during development, while a Linux deployment rejects it. A class declared Product in product.php can therefore appear to work locally and fail later. Use exact case in the filename, namespace, and references. Git may need a deliberate intermediate rename to record a case-only change on a case-insensitive filesystem. Review generated autoload warnings rather than ignoring them. Test on the target platform or a compatible CI environment. Do not 'fix' a mapping problem by adding ad hoc require statements everywhere, because that hides the inconsistency and makes future classes fail unpredictably.
Load Composer once at the application boundary
The entry script normally requires vendor/autoload.php once, using a trusted path relative to the project root. After that, namespaced classes can be instantiated without manual includes for each class. Missing vendor means dependencies were not installed or the release artifact is incomplete. Updating autoload configuration requires regenerating Composer's autoload metadata with the appropriate command. dump-autoload rebuilds that metadata without intentionally resolving a new dependency set. Production optimized autoloading can reduce lookup work, but authoritative classmaps need care when classes are generated or discovered dynamically. Choose an optimization supported by your application's loading behavior and verify it before deployment.
Separate application, tests and helper functions
A production psr-4 namespace can map App\ to src, while autoload-dev maps Tests\ to tests. That keeps test helpers out of ordinary no-dev installation policy. PSR-4 is designed around classes and related named structures, not arbitrary function lookup. Composer's files autoload mechanism can include a small reviewed helper file when a project needs global functions, but avoid turning it into a bag of side effects. Including a file should not unexpectedly open databases, send mail, or output text. Keep initialization explicit at the application boundary. Composer can map several namespace prefixes or directories; use those features to support a clear layout rather than making one class's location ambiguous.
Know what other PSR standards address
PSR-12 describes coding-style conventions, while PSR-3 defines a logger interface and PSR-7 describes HTTP message interfaces. PSR-11 concerns container interfaces, and other accepted recommendations address additional interoperability needs. A project need not claim every standard to use PSR-4 correctly. Select a standard when a shared interface helps packages work together or when a style convention improves collaboration. Read the exact current document rather than treating 'PSR compliant' as a universal quality label. An interface specifies a contract, not a particular implementation or framework. For example, using a PSR-3 logger allows compatible logger implementations, but it does not automatically choose your log retention or redact secrets.
Debug class loading by checking the mapping
Start with the fully qualified class name and calculate its expected path from the configured prefix. Check the file exists with exact case, contains the correct namespace and declaration, and can be parsed by the supported PHP runtime. Verify vendor/autoload.php is loaded and metadata was regenerated after configuration changes. Look for duplicate class declarations or a conflicting prefix mapping. Do not change package versions first when the problem is a wrong filename. Static analysis and a simple controlled class-instantiation test can catch many mistakes. Keep classes free of import-time output so loading one does not cause headers-already-sent errors. Autoloading should make dependencies easier to locate, not introduce hidden application behavior.
Practice task and worked solution
A class named App\Billing\Invoice is stored in src/billing/invoice.php and fails after Linux deployment. The solution renames the directories and file to Billing/Invoice.php, verifies namespace App\Billing, and regenerates autoload metadata when needed. Add a Tests\ mapping under autoload-dev without including test files in production loading. Explain the difference between use App\Billing\Invoice and requiring vendor/autoload.php. Then introduce a reviewed PSR-3 logger interface in a service and show how it makes the logger implementation replaceable without deciding the application's privacy policy. Keep actual dependency installation and deployment outside this conceptual exercise.
Continue learning
Review namespaces and Composer, classes, and advanced OOP.
The official PSR-4 standard defines namespace-to-path mapping and case requirements.
PSR Standards and Autoloading Examples
Each example shows the code, the output it produces and what each part does.
Map a class to its PSR-4 file
The project has a Composer mapping App\\ to src/. After installing dependencies or running dump-autoload, the entry script loads the generated autoloader.
When the mapping, file path, and generated autoloader are correct, the separate entry script prints Pen. The combined listing is explanatory: put the class and entry script in the stated separate files rather than copying both responsibilities into one file.
<?php
// src/Catalog/Product.php
namespace App\Catalog;
final class Product {
public function __construct(public readonly string $name) {}
}
// Separate entry script:
// require __DIR__ . '/vendor/autoload.php';
// $product = new \App\Catalog\Product('Pen');
// echo $product->name;Separate entry script with a valid PSR-4 mapping: PenPSR Standards and Autoloading FAQ
Does use load the file?
No. A use statement only aliases a name so you can write User instead of App\Models\User. Autoloading resolves the class when needed: the first time code actually uses the class, the registered autoloader finds and includes its file.
Does PSR-4 load functions automatically?
No. It maps named class-like structures, meaning classes, interfaces, traits and enums, to files. Composer's files autoload setting serves a different purpose: it includes listed files of functions on every request.
Why does Windows work but Linux fail?
Case sensitivity often exposes incorrect paths. Windows and default macOS filesystems ignore case, so Models/user.php is found for User; Linux treats them as different files. Make every folder and file name match the namespace and class exactly.
Does PSR-4 require a framework?
No. Composer can generate the loader for a small project: add an autoload.psr-4 entry to composer.json, run composer dump-autoload and require vendor/autoload.php.
PSR Standards and Autoloading Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Product.php contains namespace App\\Other but lives under src/Catalog. What should change?
PSR Standards and Autoloading Quiz
2 questions to check what you learned.
Where does App\\Catalog\\Product map under App\\ -> src/?
- src/product/catalog.txt
- Any file regardless of case
- src/Catalog/Product.php
- vendor/App.php only
What does dump-autoload primarily regenerate?
- Every package version unconditionally
- Database tables
- Mail credentials
- Autoload metadata