Namespaces (PHP 5.3) group names so that two libraries can both define a class called
Client. They work a little like folders: \ separates the parts,
and a leading \ means the root. The manual’s
Namespaces chapter
gives the full rules.
Declaration
<?php
declare(strict_types=1);
namespace App\Reports;
const VERSION = 1;
function run(): void {}
class Monthly {}
- Only classes (with interfaces, traits and enums), functions and constants declared
with
constbelong to a namespace. Variables and other code do not.define()does not use the current namespace: give it the full name. - The declaration must be the first statement of the file. The only thing that may
come before it is a
declarestatement. Comments are fine, but inline HTML is not, so a byte order mark or blank line before<?phpis a fatal error. - A name in a namespace declaration cannot start with a backslash. Keywords are allowed in names since PHP 8.0.
- One namespace can be declared in any number of files.
- Code with no namespace is in the global namespace.
__NAMESPACE__is then an empty string.
Several namespaces in one file
The manual strongly discourages this, except for bundling scripts into one file. There are two forms, and they cannot be mixed in a file.
namespace One;
class A {}
namespace Two;
class A {}
namespace applies until the next onenamespace One {
class A {}
}
namespace { // global code
new One\A();
}
declareImporting with use
namespace App;
use Vendor\Lib\Client; // imports the name Client
use Vendor\Lib\Server as Host; // under another name
use Vendor\Lib; // a namespace: Lib\Thing
use function Vendor\Lib\connect; // a function
use const Vendor\Lib\TIMEOUT; // a constant
use Vendor\Lib\{Reader, Writer as W}; // group use
new Client(); // Vendor\Lib\Client
connect(); // Vendor\Lib\connect
useonly creates an alias. It does not load anything, and importing a name that does not exist is not an error until it is used.- It must be at the top level of a file or namespace. It cannot be inside a function
or a block. A
useinside a class body means something else: it inserts a trait. - Imports apply per file. An included file does not inherit them.
- Imported names are absolute, so a leading
\is unnecessary. - Group use (PHP 7.0) imports several names with a shared prefix. It may mix
kinds, as in
use A\{B, function c, const D};. A trailing comma is allowed since PHP 7.2. - Imports work at compile time, so they do not apply to names built at run time. A
name held in a string is always fully qualified:
$c = 'Vendor\Lib\Client'; new $c;.
Kinds of name
| Kind | Example | Token (PHP 8.0) |
|---|---|---|
| Unqualified | Foo | T_STRING |
| Qualified | Foo\Bar | T_NAME_QUALIFIED |
| Fully qualified | \Foo\Bar | T_NAME_FULLY_QUALIFIED |
| Relative | namespace\Foo | T_NAME_RELATIVE |
Name resolution
Names are resolved in this order (manual):
- A fully qualified name resolves to the name without the leading backslash.
- A relative name replaces
namespacewith the current namespace. In the global namespace, the prefix is removed. - For a qualified name, the first part is looked up in the class and namespace import
table.
use A\B\C;makesC\D\Eresolve toA\B\C\D\E. - For a qualified name with no import, the current namespace is added at the front.
- An unqualified name is looked up in the import table for its kind: class-like names, functions and constants have separate tables.
- An unqualified class-like name with no import gets the current namespace.
- An unqualified function or constant with no import, outside the global namespace, is resolved at run time: first in the current namespace, then in the global namespace.
namespace A;
use B\D, C\E as F;
foo(); // A\foo, then global foo
\foo(); // global foo
my\foo(); // A\my\foo
F(); // A\F, then global F
new B(); // class A\B
new D(); // class B\D, by import
new F(); // class C\E, by import
new \B(); // global class B
Fallback to the global namespace
Functions and constants fall back to the global namespace. Classes do not.
namespace Lib;
echo strlen('hi'); // Lib\strlen if it exists, otherwise global strlen
echo INI_ALL; // Lib\INI_ALL if it exists, otherwise global INI_ALL
new ArrayObject(); // Error: class Lib\ArrayObject not found
new \ArrayObject(); // OK
Because of the fallback, an unqualified function name can be shadowed by a function
in the current namespace. Writing \strlen() or
use function strlen; pins it to the global function.
The namespace keyword
namespace\name refers to a name in the current namespace, as
self does for classes. Foo::class resolves a class name
at compile time without loading the class.