Easy Tutorial
❮ Php Serialize Function Func Array Fill ❯

PHP Namespaces

PHP namespaces were introduced in PHP 5.3. If you have studied C# and Java, namespaces are not new to you. However, they hold significant importance in PHP.

PHP namespaces can address the following two types of issues:

Defining Namespaces

By default, all constants, classes, and function names are placed in the global namespace, just as they were before PHP supported namespaces.

Namespaces are declared using the namespace keyword. If a file contains a namespace, it must declare the namespace before any other code. The syntax is as follows:

<?php  
// Define code in the 'MyProject' namespace  
namespace MyProject;  

// ... code ...

You can also define different namespaces in the same file, like this:

<?php  
namespace MyProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }

namespace AnotherProject;

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
?>

It is not recommended to use this syntax to define multiple namespaces in a single file. It is recommended to use the bracketed syntax below.

<?php
namespace MyProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}

namespace AnotherProject {
    const CONNECT_OK = 1;
    class Connection { /* ... */ }
    function connect() { /* ... */  }
}
?>

Combining global non-namespaced code with namespaced code can only be done using the bracketed syntax. Global code must be enclosed in a namespace statement without a name, like this:

<?php
namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace { // global code
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>

The only valid code before declaring a namespace is the declare statement for defining the source file encoding. No non-PHP code, including whitespace, can appear before the namespace declaration.

<?php
declare(encoding='UTF-8'); // Defining multiple namespaces and code not in a namespace
namespace MyProject {

const CONNECT_OK = 1;
class Connection { /* ... */ }
function connect() { /* ... */  }
}

namespace { // global code
session_start();
$a = MyProject\connect();
echo MyProject\Connection::start();
}
?>

The following code will result in a syntax error:

<html>
<?php
namespace MyProject; // A fatal error - the namespace must be the first statement in the script
?>

Sub-Namespaces

Similar to the relationship between directories and files, PHP namespaces allow specifying hierarchical namespace names. Therefore, namespace names can be defined in a hierarchical manner:

<?php
namespace MyProject\Sub\Level;  // Declare a hierarchical single namespace

const CONNECT_OK = 1;
class Connection { /* ... */ }
function Connect() { /* ... */  }

?>

The example above creates the constant MyProject\Sub\Level\CONNECT_OK, the class MyProject\Sub\Level\Connection, and the function MyProject\Sub\Level\Connect.


Namespace Usage

Class names in PHP namespaces can be referenced in three ways:

-

Non-qualified name, or a class name without a prefix, such as $a = new foo(); or foo::staticmethod();. If the current namespace is currentnamespace, foo will be resolved to currentnamespace\foo. If the code using foo is global, not enclosed in any namespace, foo will be resolved to foo. Warning: If the function or constant in the namespace is not defined, the non-qualified function name or constant name will be resolved to the global function name or constant name.

-

Qualified name, or a name with a prefix, such as $a = new subnamespace\foo(); or subnamespace\foo::staticmethod();. If the current namespace is currentnamespace, foo will be resolved to currentnamespace\subnamespace\foo. If the code using foo is global, not enclosed in any namespace, foo will be resolved to subnamespace\foo.

-

Fully qualified name, or a name with a global prefix operator, such as $a = new \currentnamespace\foo(); or \currentnamespace\foo::staticmethod();. In this case, foo is always resolved to the literal name currentnamespace\foo in the code.

Here is an example using these three methods:

file1.php file code

<?php
namespace Foo\Bar\subnamespace; 

const FOO = 1;
function foo() {}
class foo
{
    static function staticmethod() {}
}
?>

file2.php file code

<?php
namespace Foo\Bar;
include 'file1.php';

const FOO = 2;
function foo() {}
class foo
{
    static function staticmethod() {}
}

/* Non-qualified name */
foo(); // Resolves to function Foo\Bar\foo
foo::staticmethod(); // Resolves to class Foo\Bar\foo, method staticmethod
echo FOO; // Resolves to constant Foo\Bar\FOO

/* Qualified name */
subnamespace\foo(); // Resolves to function Foo\Bar\subnamespace\foo
subnamespace\foo::staticmethod(); // Resolves to class Foo\Bar\subnamespace\foo,
                                  // and method staticmethod
echo subnamespace\FOO; // Resolves to constant Foo\Bar\subnamespace\FOO

/* Fully qualified name */
\Foo\Bar\foo(); // Resolves to function Foo\Bar\foo
\Foo\Bar\foo::staticmethod(); // Resolves to class Foo\Bar\foo, method staticmethod
echo \Foo\Bar\FOO; // Resolves to constant Foo\Bar\FOO
?>

Note that you can access any global class, function, or constant using a fully qualified name, such as \strlen() or \Exception or \INI_ALL.

Accessing global classes, functions, and constants within a namespace:

<?php
namespace Foo;

function strlen() {}
const INI_ALL = 3;
class Exception {}

$a = \strlen('hi'); // Calls global function strlen
$b = \INI_ALL; // Accesses global constant INI_ALL
$c = new \Exception('error'); // Instantiates global class Exception
?>

Namespaces and Dynamic Language Features

The implementation of PHP namespaces is influenced by the dynamic nature of the language itself. Therefore, to convert the following code to use namespaces for dynamic access to elements.

example1.php file code:

<?php
class classname
{
    function __construct()
    {
        echo __METHOD__, "\n";
    }
}
function funcname()
{
    echo __FUNCTION__, "\n";
}
const constname = "global";

$a = 'classname';
$obj = new $a; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "\n"; // prints global
?>

Dynamic Access to Namespace Elements

<?php
namespace namespacename;
class classname
{
    function __construct()
    {
        echo __METHOD__, "\n";
    }
}
function funcname()
{
    echo __FUNCTION__, "\n";
}
const constname = "namespaced";

include 'example1.php';

$a = 'classname';
$obj = new $a; // prints classname::__construct
$b = 'funcname';
$b(); // prints funcname
echo constant('constname'), "\n"; // prints global

/* If using double quotes, use "\\namespacename\\classname" */
$a = '\namespacename\classname';
$obj = new $a; // prints namespacename\classname::__construct
$a = 'namespacename\classname';
$obj = new $a; // prints namespacename\classname::__construct
$b = 'namespacename\funcname';
$b(); // prints namespacename\funcname
$b = '\namespacename\funcname';
$b(); // prints namespacename\funcname
echo constant('\namespacename\constname'), "\n"; // prints namespaced
echo constant('namespacename\constname'), "\n"; // prints namespaced
?>

The namespace Keyword and the __NAMESPACE__ Constant

PHP supports two abstract ways to access elements within the current namespace: the __NAMESPACE__ magic constant and the namespace keyword.

The value of the __NAMESPACE__ constant is a string that contains the current namespace name. In global, non-namespaced code, it contains an empty string.

__NAMESPACE__ Example, code within a namespace

<?php
namespace MyProject;

echo '"', __NAMESPACE__, '"'; // prints "MyProject"
?>

__NAMESPACE__ Example, global code

<?php

echo '"', __NAMESPACE__, '"'; // prints ""
?>

The __NAMESPACE__ constant is useful for dynamically creating names, for example:

Using __NAMESPACE__ to dynamically create names

<?php
namespace MyProject;

function get($classname)
{
    $a = __NAMESPACE__ . '\\' . $classname;
    return new $a;
}
?>

The namespace keyword can be used to explicitly access elements within the current namespace or sub-namespaces. It is equivalent to the self operator in classes.

Namespace operator, code within a namespace

<?php
namespace MyProject;

use blah\blah as mine; // imports the blah\blah namespace and defines an alias mine

mine\mine(); // calls the function blah\blah\mine()
?>
namespace\blah\mine(); // calls function MyProject\blah\mine()

namespace\func(); // calls function MyProject\func()
namespace\sub\func(); // calls function MyProject\sub\func()
namespace\cname::method(); // calls static method of class MyProject\cname
$a = new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname
$b = namespace\CONSTANT; // assigns value of constant MyProject\CONSTANT to $b
?>

Namespace operator, global code

<?php

namespace\func(); // calls function func()
namespace\sub\func(); // calls function sub\func()
namespace\cname::method(); // calls static method "method" of class cname
$a = new namespace\sub\cname(); // instantiates object of class sub\cname
$b = namespace\CONSTANT; // assigns value of constant CONSTANT to $b
?>

Using Namespaces: Aliases/Imports

PHP Namespaces support two ways of aliasing or importing: aliasing class names, or aliasing namespace names.

In PHP, aliases are implemented using the use operator. Below is an example using all three possible import methods:

  1. Importing/aliasing with the use operator

    <?php
    namespace foo;
    use My\Full\Classname as Another;
    
    // The following example is the same as use My\Full\NSname as NSname
    use My\Full\NSname;
    
    // Importing a global class
    use \ArrayObject;
    
    $obj = new namespace\Another; // instantiates object of class foo\Another
    $obj = new Another; // instantiates object of class My\Full\Classname
    NSname\subns\func(); // calls function My\Full\NSname\subns\func
    $a = new ArrayObject(array(1)); // instantiates object of class ArrayObject
    // If not using "use \ArrayObject", it would instantiate an object of class foo\ArrayObject
    ?>
    
  2. Multiple use statements in one line

    <?php
    use My\Full\Classname as Another, My\Full\NSname;
    
    $obj = new Another; // instantiates object of class My\Full\Classname
    NSname\subns\func(); // calls function My\Full\NSname\subns\func
    ?>
    

Importing is performed at compile time, but dynamic class names, function names, or constant names are not affected.

  1. Importing and dynamic names
    <?php
    use My\Full\Classname as Another, My\Full\NSname;
    
    $obj = new Another; // instantiates object of class My\Full\Classname
    $a = 'Another';
    $obj = new $a; // instantiates object of class Another
    ?>
    

Additionally, importing affects only unqualified and qualified names. Fully qualified names are definite and thus not affected by importing.

  1. Importing and fully qualified names
    <?php
    use My\Full\Classname as Another, My\Full\NSname;
    
    $obj = new Another; // instantiates object of class My\Full\Classname
    $obj = new \Another; // instantiates object of class Another
    $obj = new Another\thing; // instantiates object of class My\Full\Classname\thing
    $obj = new \Another\thing; // instantiates object of class Another\thing
    ?>
    

Using Namespaces: Fallback to Global Function/Constant

<?php
namespace MyProject;

function func() {
    echo "Calling MyProject\func()\n";
}

function sub\func() {
    echo "Calling MyProject\sub\func()\n";
}

class cname {
    static function method() {
        echo "Calling MyProject\cname::method()\n";
    }
}

const CONSTANT = "MyProject\CONSTANT";

namespace\func(); // calls function MyProject\func()
namespace\sub\func(); // calls function MyProject\sub\func()
namespace\cname::method(); // calls static method of class MyProject\cname
$a = new namespace\sub\cname(); // instantiates object of class MyProject\sub\cname
$b = namespace\CONSTANT; // assigns value of constant MyProject\CONSTANT to $b
?>

Within a namespace, when PHP encounters an unqualified class, function, or constant name, it uses different prioritization strategies to resolve the name. Class names are always resolved to the names in the current namespace. Therefore, when accessing system internal or non-namespaced class names, you must use the fully qualified name, for example:

  1. Accessing a global class within a namespace
    <?php
    namespace A\B\C;
    class Exception extends \Exception {}
    
    $a = new Exception('hi'); // $a is an object of class A\B\C\Exception
    $b = new \Exception('hi'); // $b is an object of class Exception
    
    $c = new ArrayObject; // Fatal error, class A\B\C\ArrayObject not found
    ?>
    

For functions and constants, if they do not exist in the current namespace, PHP will fall back to using the functions or constants in the global namespace.

  1. Fallback to global functions/constants within a namespace
    <?php
    namespace A\B\C;
    
    const E_ERROR = 45;
    function strlen($str)
    {
        return \strlen($str) - 1;
    }
    
    echo E_ERROR, "\n"; // Outputs "45"
    echo INI_ALL, "\n"; // Outputs "7" - uses the global constant INI_ALL
    
    echo strlen('hi'), "\n"; // Outputs "1"
    if (is_array('hi')) { // Outputs "is not array"
        echo "is array\n";
    } else {
        echo "is not array\n";
    }
    ?>
    

Global Space

If no namespace is defined, all class and function definitions are in the global space, just as they were before PHP introduced the concept of namespaces. Prepending a name with a \ indicates that the name is in the global space, even if it is within another namespace.

Example of using the global space

<?php
namespace A\B\C;

/* This function is A\B\C\fopen */
function fopen() { 
     /* ... */
     $f = \fopen(...); // Calls the global fopen function
     return $f;
} 
?>

Namespace Order

Since the introduction of namespaces, one of the most common mistakes is understanding the search path for a class when it is used.

<?php
namespace A;
use B\D, C\E as F;

// Function calls

foo();      // First tries to call the function foo() defined in namespace "A"
            // Then tries to call the global function "foo"

\foo();     // Calls the global space function "foo" 

my\foo();   // Calls the function "foo" defined in namespace "A\my" 

F();        // First tries to call the function "F" defined in namespace "A" 
            // Then tries to call the global function "F"

// Class references

new B();    // Creates an object of the class "B" defined in namespace "A"
            // If not found, attempts to autoload class "A\B"

new D();    // Uses the import rules, creates an object of the class "D" defined in namespace "B"
            // If not found, attempts to autoload class "B\D"

new F();    // Uses the import rules, creates an object of the class "E" defined in namespace "C"
            // If not found, attempts to autoload class "C\E"

new \B();   // Creates an object of the class "B" defined in the global space
            // If not found, attempts to autoload class "B"

new \D();   // Creates an object of the class "D" defined in the global space
            // If not found, attempts to autoload class "D"

new \F();   // Creates an object of the class "F" defined in the global space
            // If not found, attempts to autoload class "F"

// Calling static methods or namespace functions in another namespace

B\foo();    // Calls the function "foo" in namespace "A\B"

B::foo();   // Calls the "foo" method of the class "B" defined in namespace "A"
            // If class "A\B" is not found, attempts to autoload class "A\B"

D::foo();   // Uses the import rules, calls the "foo" method of the class "D" defined in namespace "B"
            // If class "B\D" is not found, attempts to autoload class "B\D"
\B\foo();   // Calls the function "foo" in namespace "B"

\B::foo();  // Calls the "foo" method of class "B" in the global namespace
            // If class "B" is not found, attempts to autoload class "B"

// Static method or function in the current namespace

A\B::foo();   // Calls the "foo" method of class "B" defined in namespace "A\A"
              // If class "A\A\B" is not found, attempts to autoload class "A\A\B"

\A\B::foo();  // Calls the "foo" method of class "B" defined in namespace "A"
              // If class "A\B" is not found, attempts to autoload class "A\B"
?>

Name resolution follows these rules:

❮ Php Serialize Function Func Array Fill ❯