Php/docs/language.namespaces.faq
FAQ: things you need to know about namespaces
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
This FAQ is split into two sections: common questions, and some specifics of implementation that are helpful to understand fully.
First, the common questions.
- If I don't use namespaces, should I care about any of this?
- How do I use internal or global classes in a namespace?
- How do I use namespaces classes functions, or constants in their own namespace?
- How does a name like
\my\name
or\name
resolve? - How does a name like
my\name
resolve? - How does an unqualified class name like
name
resolve? - How does an unqualified function name or unqualified constant name like
name
resolve?
There are a few implementation details of the namespace implementations that are helpful to understand.
- Import names cannot conflict with classes defined in the same file.
- Nested namespaces are not allowed.
- Neither functions nor constants can be imported via the
use
statement. - Dynamic namespace names (quoted identifiers) should escape backslash.
- Undefined Constants referenced using any backslash die with fatal error
- Cannot override special constants NULL, TRUE, FALSE, ZEND_THREAD_SAFE or ZEND_DEBUG_BUILD
If I don't use namespaces, should I care about any of this?
No. Namespaces do not affect any existing code in any way, or any as-yet-to-be-written code that does not contain namespaces. You can write this code if you wish:
Example #1 Accessing global classes outside a namespace
<?php$a = new \stdClass;
This is functionally equivalent to:
Example #2 Accessing global classes outside a namespace
<?php$a = new stdClass;
How do I use internal or global classes in a namespace?
Example #3 Accessing internal classes in namespaces
<?phpnamespace foo;$a = new \stdClass;function test(\ArrayObject $typehintexample = null) {}$a = \DirectoryIterator::CURRENT_AS_FILEINFO;// extending an internal or global classclass MyException extends \Exception {}?>
=== How do I use namespaces classes, functions, or constants in their own namespace? ===
Example #4 Accessing internal classes, functions or constants in namespaces
<?phpnamespace foo;class MyClass {}// using a class from the current namespace as a type hintfunction test(MyClass $typehintexample = null) {}// another way to use a class from the current namespace as a type hintfunction test(\foo\MyClass $typehintexample = null) {}// extending a class from the current namespaceclass Extended extends MyClass {}// accessing a global function$a = \globalfunc();// accessing a global constant$b = \INI_ALL;?>
=== How does a name like \my\name
or \name
resolve? ===
Names that begin with a \
always resolve to what they
look like, so \my\name
is in fact my\name
,
and \Exception
is Exception
.
Example #5 Fully Qualified names
<?phpnamespace foo;$a = new \my\name(); // instantiates "my\name" classecho \strlen('hi'); // calls function "strlen"$a = \INI_ALL; // $a is set to the value of constant "INI_ALL"?>
How does a name like my\name
resolve?
Names that contain a backslash but do not begin with a backslash like
my\name
can be resolved in 2 different ways.
If there is
an import statement that aliases another name to my
, then
the import alias is applied to the my
in my\name
.
Otherwise, the current namespace name is prepended to my\name
.
Example #6 Qualified names
<?phpnamespace foo;use blah\blah as foo;$a = new my\name(); // instantiates "foo\my\name" classfoo\bar::name(); // calls static method "name" in class "blah\blah\bar"my\bar(); // calls function "foo\my\bar"$a = my\BAR; // sets $a to the value of constant "foo\my\BAR"?>
How does an unqualified class name like name
resolve?
Class names that do not contain a backslash like
name
can be resolved in 2 different ways.
If there is
an import statement that aliases another name to name
, then
the import alias is applied.
Otherwise, the current namespace name is prepended to name
.
Example #7 Unqualified class names
<?phpnamespace foo;use blah\blah as foo;$a = new name(); // instantiates "foo\name" classfoo::name(); // calls static method "name" in class "blah\blah"?>
=== How does an unqualified function name or unqualified constant name
like name
resolve? ===
Function or constant names that do not contain a backslash like
name
can be resolved in 2 different ways.
First, the current namespace name is prepended to name
.
Finally, if the constant or function name
does not exist
in the current namespace, a global constant or function name
is used if it exists.
Example #8 Unqualified function or constant names
<?phpnamespace foo;use blah\blah as foo;const FOO = 1;function my() {}function foo() {}function sort(&$a){ sort($a); $a = array_flip($a); return $a;}my(); // calls "foo\my"$a = strlen('hi'); // calls global function "strlen" because "foo\strlen" does not exist$arr = array(1,3,2);$b = sort($arr); // calls function "foo\sort"$c = foo(); // calls function "foo\foo" - import is not applied$a = FOO; // sets $a to value of constant "foo\FOO" - import is not applied$b = INI_ALL; // sets $b to value of global constant "INI_ALL"?>
Import names cannot conflict with classes defined in the same file.
The following script combinations are legal:
file1.php
<?phpnamespace my\stuff;class MyClass {}?>
another.php
<?phpnamespace another;class thing {}?>
file2.php
<?phpnamespace my\stuff;include 'file1.php';include 'another.php';use another\thing as MyClass;$a = new MyClass; // instantiates class "thing" from namespace another?>
There is no name conflict, even though the class MyClass
exists
within the my\stuff
namespace, because the MyClass definition is
in a separate file. However, the next example causes a fatal error on name conflict
because MyClass is defined in the same file as the use statement.
<?phpnamespace my\stuff;use another\thing as MyClass;class MyClass {} // fatal error: MyClass conflicts with import statement$a = new MyClass;?>
Nested namespaces are not allowed.
PHP does not allow nesting namespaces
<?phpnamespace my\stuff { namespace nested { class foo {} }}?>
However, it is easy to simulate nested namespaces like so:
<?phpnamespace my\stuff\nested { class foo {}}?>
=== Neither functions nor constants can be imported via the use
statement. ===
The only elements that are affected by use
statements are namespaces
and class names. In order to shorten a long constant or function, import its containing
namespace
<?phpnamespace mine;use ultra\long\ns\name;$a = name\CONSTANT;name\func();?>
Dynamic namespace names (quoted identifiers) should escape backslash
It is very important to realize that because the backslash is used as an escape character within strings, it should always be doubled when used inside a string. Otherwise there is a risk of unintended consequences:
Example #9 Dangers of using namespaced names inside a double-quoted string
<?php$a = new "dangerous\name"; // \n is a newline inside double quoted strings!$obj = new $a;$a = new 'not\at\all\dangerous'; // no problems here.$obj = new $a;?>
Inside a single-quoted string, the backslash escape sequence is much safer to use, but it is still recommended practice to escape backslashes in all strings as a best practice.
Undefined Constants referenced using any backslash die with fatal error
Any undefined constant that is unqualified like FOO
will
produce a notice explaining that PHP assumed FOO
was the value
of the constant. Any constant, qualified or fully qualified, that contains a
backslash will produce a fatal error if not found.
Example #10 Undefined constants
<?phpnamespace bar;$a = FOO; // produces notice - undefined constants "FOO" assumed "FOO";$a = \FOO; // fatal error, undefined namespace constant FOO$a = Bar\FOO; // fatal error, undefined namespace constant bar\Bar\FOO$a = \Bar\FOO; // fatal error, undefined namespace constant Bar\FOO?>
Cannot override special constants NULL, TRUE, FALSE, ZEND_THREAD_SAFE or ZEND_DEBUG_BUILD
Any attempt to define a namespaced constant that is a special, built-in constant results in a fatal error
Example #11 Undefined constants
<?phpnamespace bar;const NULL = 0; // fatal error;const true = 'stupid'; // also fatal error;// etc.?>