Namespaces and PSR-4 Autoloading
By the end of this lesson you'll organise PHP code the way every real project does — group classes under namespace s, import them with use , understand fully-qualified names and the global \ root, and let Composer's PSR-4 autoloader load each class on demand so you never write a chain of require statements again.
Learn Namespaces and PSR-4 Autoloading in our free PHP course — an interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Php course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ Declaring a Namespace
A namespace is a label that groups related classes so their names never collide with code elsewhere. You declare it with namespace App\Service; as the first statement in the file. Everything defined below — classes, functions, constants — now lives under that prefix, so the class Mailer is really App\Service\Mailer . Two libraries can each ship a Mailer and never clash.
The convention is to mirror your folder structure: App\Service\Mailer sits in src/Service/Mailer.php . That mirroring is exactly what makes autoloading possible, as you'll see below.
2️⃣ Importing with use & Fully-Qualified Names
To reach a class in another namespace you can write its fully-qualified name — the whole path from the global root, with a leading backslash: \App\Service\Mailer . Writing that every time is tedious, so the use statement imports the name once, letting you write the short Mailer for the rest of the file. Remember: use only creates an alias — it does not load any file.
Both objects above are the same class — one reached by the imported short name, one by the fully-qualified path. Inside a namespace, a bare name like Mailer is resolved relative to the current namespace first, which is why the explicit leading \ matters.
3️⃣ Aliases & the Global \ Namespace
When two imports share a short name, rename one with as : use App\Service\Logger as ServiceLogger; . And remember that PHP's built-ins — DateTime , strlen , array_map — all live in the global namespace . Inside your own namespace, prefix them with a leading \ to say "look in the global root", which is also slightly faster than letting PHP fall back to it.
For classes the leading backslash is required (otherwise new DateTime() would look for App\Report\DateTime ). For functions and constants PHP has a global fallback, but writing \strlen() is explicit and avoids surprises.
4️⃣ PSR-4 Autoloading with Composer
PSR-4 is the standard that maps a namespace prefix to a base folder . You declare it in composer.json under autoload.psr-4 — for example App\ to src/ . After editing it you run composer dump-autoload to regenerate the maps. Now Composer can translate any fully-qualified class name straight into a file path.
With that mapping in place, your entry script needs just one include — vendor/autoload.php — and then you simply use classes. Composer loads each file the first time the class is referenced, in the right order, exactly once.
This is why the one-class-per-file convention exists: each file defines a single class whose name matches the file name, so App\Model\User resolves unambiguously to src/Model/User.php .
5️⃣ Why Not Just require Everything?
Before autoloaders, every file began with a wall of require lines. That approach is fragile : move a file and the paths break, and you load classes even on requests that never use them. It is order-dependent : a class that extends another must be required after its parent. And it is repetitive : the same includes copied into file after file. Autoloading replaces all of it with a single registration line and on-demand loading.
Now you try the two core skills — declaring/importing, and wiring up the autoloader.
Fill in each ___ using the 👉 hint, then run it and check it against the Output panel.
One more. Finish the PSR-4 mapping and the autoloader include so the class loads on its own.
📋 Quick Reference — Namespaces & Autoloading
No code is filled in this time — just a brief and an outline. Build the two namespaced classes, wire them up with PSR-4, run composer dump-autoload , then check your result against the expected output in the comments. This is exactly how every real project is structured.
Practice quiz
What does the statement namespace App\Service; do at the top of a file?
- It places every class, function, and constant in that file under the App\Service namespace
- It imports the App\Service class
- It creates a new folder called App/Service
- It autoloads all files in App/Service
Answer: It places every class, function, and constant in that file under the App\Service namespace. A namespace declaration must be the first statement in a file and puts everything defined below it under that namespace, preventing name clashes.
What is a fully-qualified class name?
- A class name written in ALL CAPS
- Any class whose name is longer than ten characters
- A name written from the global root with a leading backslash, e.g. \App\Service\Mailer
- A class that has no namespace
Answer: A name written from the global root with a leading backslash, e.g. \App\Service\Mailer. A fully-qualified name starts with a leading backslash and lists the whole path from the global namespace, so it is unambiguous no matter where it is used.
Why does PHP code that calls strlen() inside a namespace sometimes use \strlen()?
- Because strlen is deprecated
- Because the leading backslash tells PHP to look in the global namespace, not the current one
- Because namespaced code cannot call functions
- Because strlen needs an argument
Answer: Because the leading backslash tells PHP to look in the global namespace, not the current one. Built-in functions live in the global namespace. A leading backslash (\strlen) forces the global lookup, which is also marginally faster than the fallback search.
What does the use statement do?
- It includes a file like require
- It defines a new namespace
- It runs a function immediately
- It imports a class, function, or constant so you can refer to it by its short name
Answer: It imports a class, function, or constant so you can refer to it by its short name. use App\Service\Mailer; lets you write Mailer instead of the full path for the rest of the file. It does not load any file by itself.
How do you create an alias for an imported class?
- use App\Service\Mailer as M;
- alias App\Service\Mailer M;
- use M = App\Service\Mailer;
- use App\Service\Mailer alias M;
Answer: use App\Service\Mailer as M;. The as keyword renames an import: use App\Service\Mailer as M; is handy when two classes share a short name.
What does PSR-4 define?
- A coding style for indentation
- A standard mapping from a namespace prefix to a base directory so classes load automatically
- A database connection format
- A way to compress files
Answer: A standard mapping from a namespace prefix to a base directory so classes load automatically. PSR-4 is the autoloading standard that maps a namespace prefix (e.g. App\) to a base folder (e.g. src/), so each class file is found from its fully-qualified name.
In composer.json, where do you declare a PSR-4 mapping?
- Under the config key
- Under the require key
- Under the scripts key
- Under the autoload key, inside a psr-4 object
Answer: Under the autoload key, inside a psr-4 object. You add it under autoload.psr-4, for example { "autoload": { "psr-4": { "App\\": "src/" } } }, mapping the App\ prefix to the src/ directory.
After editing the autoload section of composer.json, what must you run?
- php -S localhost
- composer install --no-dev
- composer dump-autoload
- composer require autoload
Answer: composer dump-autoload. composer dump-autoload regenerates the autoloader maps so Composer knows about your new namespace mapping or newly added classes.
Why is scattering require statements throughout a codebase considered bad practice?
- It is fragile and repetitive: paths break when files move, classes load even when unused, and order matters
- require cannot load classes at all
- PHP forbids more than one require per file
- require is slower than echo
Answer: It is fragile and repetitive: paths break when files move, classes load even when unused, and order matters. Manual require chains are brittle and order-dependent. An autoloader loads each class on demand, exactly once, from a single registration line.
What is the one-class-per-file convention that PSR-4 relies on?
- Each file defines exactly one class whose name matches the file name
- All classes go in a single big file
- Each class must be under 100 lines
- Every file may contain only comments
Answer: Each file defines exactly one class whose name matches the file name. PSR-4 maps a class name to a file path, so each class needs its own file named after it (User -> User.php) for the autoloader to find it.