PHP Namespaces
Namespaces were introduced into PHP from version 5.3 onwards. They allow the developer to seperate their code into modules or groups which inturn makes the code easier to read. Namespaces prevent class and function name conflicts, it allows you to have numerous classes with the same name, as long as they are in different namespaces. Namespaces also make the old Zend/PEAR style of class name redundant (Framework_Database_Mysql_Query) because there will no longer be any class name conflicts.
Note: throughout the tutorial we will use the hypothetical files.
/Framework/Database/Mysql/Query.php
/lib/myClass.php
/index.php
The Basics
To declare a namespace you simply use the namespace keyword followed by the name of your namespace. You can specify sub namespaces by using the backslash ( \ ). Best practices state that your namespace path should match the directory path. For example the file /Framework/Database/Mysql/Query.php should have the namespace Framework\Database\Mysql and the name of the class should be Query. You should have one namespace and class per file.
Using Namespaces
In /lib/myClass.php we declare a namespace, lib, and then define a simple class, myClass. In our index.php file we include the class and instantiate it. Because myClass is in the namespace lib, we must refer to the class as lib\myClass, not just myClass. An alternate way to get namespaced classes is to use the use keyword. By specifying what classes you are use-ing at the top of the script it’s easy to look back at your code to see the dependencies for each page. You can also use foo as bar. This essentially renames class foo as bar. You’ll need to do this if you are use-ing two or more classes with the same name (namespaces will be different). Otherwise you will get name errors. Examples below.
/lib/myClass.php
namspace lib;
class myClass
{
public function foo()
{
echo 'hello world';
}
}
index.php
require 'lib/myClass.php'; //Error, Class not found. $bar = new myClass(); //Displays hello world on the screen. $bar = new lib\myClass(); $bar->foo(); //Displays hello world on the screen use lib\myClass; $bar = new myClass(); $bar->foo(); //Displays hello world use lib\myClass as newName; $bar = new newName(); $bar->foo();
Implementing an Autoloader
Rather than including every file you think you will need in your script, you can implement an autoloader. The autoloader is run every time a class that hasn’t been defined is called. In our autoload function we can translate a namespace-d class name into a file to include. Assuming we follow the convention of namespaces mapping to directories this is relatively simple.
function __autoload($class)
{
$file = str_replace('\\', '/', $class) . '.php';
if(file_exists($file))
{
require $file;
}
}
So if we called
$db = new \Framework\Database\Mysql\Query();
The autoloader would include the file Framework/Database/Mysql/Query.php where (if you were following convention) there would be a class called Query. Notice that the autoload function replaces two backslashes with a foward slash – even though the namespaces only have singular backslashes. This is because the backslash is the escape character for PHP and by putting two backslashes, it evaluates to one backslash.
Gotchas
Built in class names returning as not found.
In your existing code you may use classes built into PHP such as Exception, StdClass, Mysqli etc.. When working with namespaces you must remember to prefix these with the backslash to indicate that you want to use the class from the root namespace, the PHP library – not your own version of the class that has the same name.
Relative namespaces.
If in /Framework/Database/Mysql/Query.php we needed to use the class in /lib/MyClass.php then you would most likely use the use statement and write something like below.
Query.php
namespace Framework\Database\Mysql;
use lib\Myclass;
class Query{}
However this will error out. Why? Because PHP is trying to find the class located at \Framework\Database\Mysql\lib\myClass. We need to explicitly define that the namespace path is taken from the root of our application so we prepend a backslash and it will work as intended.
namespace Framework\Database\Mysql;
use \lib\myClass;
class Query{}
If you have any questions about namespaces in PHP feel free to ask them in the comments below.

