Namespaces and autoloading explained
In a project with third-party libraries there are bound to be several classes called “Client” or “Logger”. Namespaces solve this — and autoloading ensures that nobody has to include files by hand any more.
What you will learn
A namespace is a surname for classes
Without namespaces, each class could exist only once per application. Since every project uses third-party libraries today, that would be untenable. A namespace puts a path in front of the class name.
// File: src/Auftrag/Position.php
declare(strict_types=1);
namespace Firma\Shop\Auftrag;
final class Position
{
// ...
}
// The fully qualified name is now:
// Firma\Shop\Auftrag\PositionA second class `Position` in a different namespace is no problem, because the fully qualified name is different.
use shortens names, it loads nothing
declare(strict_types=1);
namespace Firma\Shop\Rechnung;
use Firma\Shop\Auftrag\Position;
use Firma\Lager\Position as Lagerposition;
final class Rechnungszeile
{
public function __construct(
private readonly Position $position,
private readonly ?Lagerposition $bestand = null,
) {
}
}A common misconception: `use` does not include a file. It only defines which fully qualified name is meant when the short one appears in the code. The file is loaded only on first access — by autoloading.
Autoloading: from name to file path
In the past, every file began with a series of `require` lines. Today you register a function that PHP calls as soon as an unknown class is needed. In practice, Composer handles this according to the PSR-4 convention: a namespace prefix is mapped to a directory, and the rest of the name to the path beneath it.
{
"autoload": {
"psr-4": {
"Firma\\Shop\\": "src/"
}
}
}The mapping is literal: upper and lower case matter, because the file system on the server distinguishes them — even if your own machine perhaps does not.
An example from practice
“Class not found” — “Class not found” — four typical causes: namespace and path do not match; the mapping is new and Composer does not know it yet; a use statement is missing or a global class is referenced inside the namespace without a leading backslash; vendor/ was not installed.
A third, rarer cause is the optimised autoloader: `composer dump-autoload -o` creates a fixed list of all classes. A class whose path does not match the rule is missing from it — and is only noticed in the production environment, because optimisation is used there and not on the development machine.
Common misconceptions
Further sources
- PHP manual: Namespaces the language reference
- PSR-4: Autoloader the convention behind the mapping
- Composer: Autoloading the configuration in detail
About the author
Fabian Lücker is managing partner of PHP-Schmiede KG in Rheine and has worked in software development since 2007. He is responsible for development and design, and writes here about decisions that arise in real projects.