A PHP namespace puts classes, functions and constants under a prefix so their names cannot collide with someone else's. You declare it with namespace App\Models; as the first statement of a file, and other files refer to the class as \App\Models\User, or import it with use App\Models\User; and write just User.
Inside the namespace, User means App\Models\User. User::class gives the full name as a string without creating anything, which is handy for logging and for autoloaders.
Two namespaces in one file
A real project puts one namespace in each file. For a self-contained demo, one file may hold several namespaces when each is wrapped in braces. Code that belongs to no namespace goes in namespace { }:
Two classes called Order live side by side because their full names differ. That is exactly the problem namespaces solve once you install libraries: your Order, a payment library's Order and a PDF library's Order no longer clash.
Import with use, and alias with as
Writing \Shop\Order everywhere is noisy. use at the top of a file (or namespace block) imports a name so you can use the short form. When two imports would end in the same short name, as gives one of them a different name:
use only creates a short name for the rest of the file. It does not load a file or run code, and it works the same whether or not the class exists yet. Grouped imports are also allowed: use Shop\{Order, Invoice};.
use function and use const
Functions and constants in a namespace are imported with use function and use const:
Global classes need a backslash
Inside a namespace, an unqualified class name is resolved relative to that namespace, so new DateTime() inside namespace App; looks for App\DateTime. Functions and constants are different: if App\strlen does not exist, PHP falls back to the global strlen. Classes never fall back.
The catch (\Error $e) needed a backslash for the same reason: without it PHP would look for App\Error, never match the real error, and the script would stop with an uncaught Error. Fix it either with a leading backslash, as above, or with use DateTime; at the top of the file. The same applies to \Exception, \Throwable and every other built-in class; see try catch for catching them.
Autoloading and PSR-4
In a project, each class lives in its own file, and the file path follows the namespace. PSR-4 is the convention: a namespace prefix maps to a base folder, and the rest of the name becomes the path. An autoloader registered with spl_autoload_register() then loads a class file the first time the class is used. This block writes two class files to disk and autoloads them:
Each class file is loaded once, at the moment the class is first needed. In real projects you do not write this function yourself: Composer generates it from a few lines in composer.json:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
After composer dump-autoload, a single require __DIR__ . '/vendor/autoload.php'; at the start of your entry script loads every App\... class on demand.
Namespace rules that cause errors
namespacemust be the first statement in the file. Onlydeclare(strict_types=1);and comments may come before it.useimports are per file. Importing a class inindex.phpdoes not make the short name work inside an included file; each file needs its ownuselines.usebelongs at the top level of the file or namespace block. Inside a class body,usemeans something else: it pulls in a trait.- Strings are never resolved:
$class = 'User'; new $class();looks for the globalUser. Store the full name, ideally withUser::class.
The last one deserves a quick check:
Frequently Asked Questions
What is a namespace in PHP?
A prefix that groups related classes, interfaces, functions and constants, like a folder for names. namespace App\Models; at the top of a file puts its User class at App\Models\User, so it cannot collide with another library's User.
What does use do in PHP?
use App\Models\User; at the top of a file lets you write User instead of the full name \App\Models\User in that file. It does not load or include anything; loading the class file is the autoloader's job. use ... as Alias; picks a different short name.
Why do I get Class not found inside a namespace?
Inside namespace App; a bare class name is resolved relative to the namespace, so new DateTime() looks for App\DateTime. Write new \DateTime() or add use DateTime; at the top. Functions and constants fall back to the global namespace automatically, classes do not.
What is the backslash before a class name in PHP?
A leading backslash makes the name fully qualified, starting from the global namespace: \Exception is always PHP's built-in Exception, whatever namespace the code is in. Without it, the name is resolved relative to the current namespace and use imports.
How do namespaces relate to folders and PSR-4?
PHP itself does not tie namespaces to folders. PSR-4 is the convention that does: a prefix such as App\ maps to a directory such as src/, so App\Models\User lives in src/Models/User.php. Composer's autoloader follows it, which is why the two usually match.