(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.
\my\name or \name
resolve?
my\name resolve?
name resolve?
name resolve?
There are a few implementation details of the namespace implementations that are helpful to understand.
null, true or false
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;
?>
Example #3 Accessing internal classes in namespaces
<?php
namespace foo;
$a = new \stdClass;
function test(\ArrayObject $parameter_type_example = null) {}
$a = \DirectoryIterator::CURRENT_AS_FILEINFO;
// extending an internal or global class
class MyException extends \Exception {}
?>
Example #4 Accessing internal classes, functions or constants in namespaces
<?php
namespace foo;
class MyClass {}
// using a class from the current namespace as a parameter type
function test(MyClass $parameter_type_example = null) {}
// another way to use a class from the current namespace as a parameter type
function test(\foo\MyClass $parameter_type_example = null) {}
// extending a class from the current namespace
class Extended extends MyClass {}
// accessing a global function
$a = \globalfunc();
// accessing a global constant
$b = \INI_ALL;
?>\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
<?php
namespace foo;
$a = new \my\name(); // instantiates "my\name" class
echo \strlen('hi'); // calls function "strlen"
$a = \INI_ALL; // $a is set to the value of constant "INI_ALL"
?>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
<?php
namespace foo;
use blah\blah as foo;
$a = new my\name(); // instantiates "foo\my\name" class
foo\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"
?>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
<?php
namespace foo;
use blah\blah as foo;
$a = new name(); // instantiates "foo\name" class
foo::name(); // calls static method "name" in class "blah\blah"
?>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
<?php
namespace foo;
use blah\blah as foo;
const FOO = 1;
function my() {}
function foo() {}
function sort(&$a)
{
\sort($a); // calls the global function "sort"
$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"
?>The following script combinations are legal:
file1.php
<?php
namespace my\stuff;
class MyClass {}
?>another.php
<?php
namespace another;
class thing {}
?>file2.php
<?php
namespace 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.
<?php
namespace my\stuff;
use another\thing as MyClass;
class MyClass {} // fatal error: MyClass conflicts with import statement
$a = new MyClass;
?>PHP does not allow nesting namespaces
<?php
namespace my\stuff {
namespace nested {
class foo {}
}
}
?><?php
namespace my\stuff\nested {
class foo {}
}
?>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 = "dangerous\name"; // \n is a newline inside double quoted strings!
$obj = new $a;
$a = 'not\at\all\dangerous'; // no problems here.
$obj = new $a;
?>
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
<?php
namespace 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
?>