PHP Tutorial Tutorials - PHP OOP Namespaces

PHP OOP Namespaces

In PHP, namespaces are designed to solve the Name collisions problem that multiple classes/functions have the same name between the code you create and the code other author create(For example: library).

A real-life example: there are two students called "Tom". We can separate them by the ClassRoom(space).

Namespace syntax example

  • Namespace names are case-insensitive.
  • Usually,declare multiple namespaces in the different files.
  • Use \ to access the related classes, interfaces, functions and constants with namespaces

use the keyword namespace to declare a namespace in PHP.
namespace must be the first statement in the script

  1. Create a file named my.php
// !! There can't be any characters or whitespace here 
// Fatal error: Namespace declaration statement has to be the very first statement or after any declare call in the script
<?php
// !! There can't be any statement here 
namespace my\name; // see "Defining Namespaces" section

class MyClass {}
function myfunction() { echo "function";}
const MYCONST = 1;

alternatively, you use the alternate bracketed syntax.

<?php
namespace my\name{
    class MyClass {}
    function myfunction() { echo "function";}
    const MYCONST = 1;
}
?>
  1. Create another file called usage.php and access the my namespace's items.
<?php
include_once 'my.php';

$myclass = new \my\name\MyClass; // OR my\name\MyClass
\my\name\myfunction(); 
echo \my\name\MYCONST;

Much like directories and files,

A class name can be referred to in three ways:

Namespace name definitions Example resolves to
(current namespace:curNS)
resolves to
(global)
Unqualified name,
unprefixed class name
$a = new foo();
foo::staticmethod();
curNS\foo foo
Qualified name,
prefixed class name
$a = new subNS\foo();
subNS\foo::staticmethod();
curNS\subNS\foo subNS\foo
Fully qualified name
prefixed name with global prefix operator
$a = new \curNS\foo();
\curNS\foo::staticmethod();
curNS\foo curNS\foo

reference:three ways to access a file in a file system:

Referred Way Example resolve to Example(/home/foo)
Relative file name foo.txt currentdirectory/foo.txt /home/foo/foo.txt
Relative path name subdirectory/foo.txt currentdirectory/subdirectory/foo.txt /home/foo/subdirectory/foo.txt
Absolute path name /main/foo.txt /main/foo.txt /main/foo.txt

Global space

Without any namespace definition, all class and function definitions are placed into the global space.

Keyword namespace and constant __NAMESPACE__

PHP supports two ways of abstractly accessing elements within the current namespace, the __NAMESPACE__ magic constant, and the namespace keyword.

the __NAMESPACE__ magic constant contains the current namespace name( In global code, it contains an empty string )

<?php
namespace MyProject;

echo '"', __NAMESPACE__, '"'; //  "MyProject"
?> 
<?php
echo '"', __NAMESPACE__, '"'; //  ""
?> 

The namespace keyword can be used to explicitly request an element from the current namespace or a sub-namespace.

sub\functions.php

<?php
namespace Lautturi\sub;

function func(){
    echo "function in Lautturi space <br>";
}
?>

sub\cname.php

<?php
namespace Lautturi\sub;

class cname{

}
?>

myproject.php

<?php
namespace Lautturi;
include_once 'sub\function.php';
include_once 'sub\cname.php';

const MYCONST = "Lautturi";
function func(){
    echo "function in Lautturi space <br>";
}


namespace\func(); // calls function Lautturi\func()
namespace\sub\func(); // calls function Lautturi\sub\func()
namespace\cname::method(); // calls static method "method" of class Lautturi\cname
$subCname = new namespace\sub\cname(); // instantiates object of class Lautturi\sub\cname
echo namespace\MYCONST; // get value of constant Lautturi\MYCONST
?>

Recommended Structure for Namespaces

It is recommended to map namespaces with the directories and files.
Each class file only define one class.The file name is the same name as the class name.
Assume we have the project in the folder /var/www/project

project/
  |---index.php
  |---lib/ (or vender)
       |---Lau/
            |---BaseLau.php  (namespace lau;class BaseLau{})
            |---web/
                 |---App.php (namespace lau\web;class App{})
       |---XXSoft/ (vender name)
            |---Helper.php  (namespace xxsoft;class Helper{})

Example codes

project/lib/Lau/BaseLau.php

<?php
namespace lau;

class BaseLau {
    public static function getVersion()
    {
        return '1.0.9';
    }
}

project/lib/XXSoft/helper.php

<?php
namespace xxsoft;
class Helper{
    public function help()
    {
        return "helper function";
    }
}

project/lib/Lau/web/App.php

<?php
namespace lau\web;
class App{
    public function hello()
    {
        echo \lau::getVersion();
        echo \xxsoft::help();
        echo "Hello Lautturi";
    }
}

project/index.php

<?php
namespace lau\web;
class App{
    public function hello()
    {
        echo \lau\BaseLau::getVersion();
        $helper = new \xxsoft\Helper;
        echo $helper->help();
        echo "Hello Lautturi";
    }
}

namespaces: Aliasing/Importing-Using the use keyword

In PHP, aliasing is accomplished with the use operator. It will import a class to the current scope.

  • the leading backslash(\) is unnecessary and not recommended.
  • Fully qualified names are unaffected by imports
<?php
use lau\BaseLau; // same as but not recommended -> use \lau\BaseLau
use lau\BaseLau as Another
$baselau = new BaseLau();

$another = new Another();

// Fully qualified names are unaffected by imports
$obj = new Another; // instantiates object of class lau\BaseLau
$obj = new \Another; // instantiates object of class Another
$obj = new Another\thing; // instantiates object of class lau\BaseLau\thing
$obj = new \Another\thing; // instantiates object of class Another\thing

all 5 kinds of importing

<?php
namespace foo;
use My\Full\Classname as Another;

// this is the same as use My\Full\NSname as NSname
use My\Full\NSname;

// importing a global class
use ArrayObject;

// importing a function (PHP 5.6+)
use function My\Full\functionName;

// aliasing a function (PHP 5.6+)
use function My\Full\functionName as func;

// importing a constant (PHP 5.6+)
use const My\Full\CONSTANT;

$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
// without the "use ArrayObject" we would instantiate an object of class foo\ArrayObject
func(); // calls function My\Full\functionName
echo CONSTANT; // echoes the value of My\Full\CONSTANT
?> 

Modify the example codes

project/lib/Lau/BaseLau.php

<?php
namespace lau;

class BaseLau {
    public static function getVersion()
    {
        return '1.0.9';
    }
}

project/lib/XXSoft/helper.php

<?php
namespace xxsoft;
class Helper{
    public function help()
    {
        return "helper function";
    }
}

project/lib/Lau/web/App.php

<?php
namespace lau\web;
use lau\BaseLau;
use xxsoft\Helper;

class App{
    public function hello()
    {
        echo BaseLau::getVersion();
        $helper = new Helper();
        echo $helper->help();
        echo "Hello Lautturi";
    }
}

project/index.php

<?php
include_once 'lib/Lau/BaseLau.php';
include_once 'lib/Lau/web/App.php';
include_once 'lib/XXSoft/helper.php';
use Lau\web\App;

$app = new App();

$app -> hello();
?>
Date:2019-10-09 01:13:44 From:www.Lautturi.com author:Lautturi