Michiel van der Velde A statistical impossibility

30Jan/100

Namespaces in php 5.3

PHP 5.3, introduced in June 2009 and has some really interesting enhancements. Some of you may know about the promise of namespace support in php 6. Because this was a popular requested feature, namespaces have been introduced in php 5.3.

What are namespaces and why are they convenient?

'Namespaces' are default in almost every other (OOP) language, such as C++ and C#. They separate classes and other objects (such as methods) in logical units, mostly to avoid name collisions. A program (or web site, as is probably the case in php) may use several frameworks and libraries. These may hold methods and/or classes that are named the same, for example a class named Date. Prior to php 5.3, this would lead to the well known error "Could not redeclare class Date in file/name.php on line no". This, of course, could be a problem when you want to use multiple frameworks and/or third-party libraries.

The problem of name colissions was dealt with before by using something called 'poor man's namespacing', which has been used in, for example, the Zend Framework. This looks something like this:

< ?php
class Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive extends Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum
{
	public function __construct()
	{
		$this->addFilter(new Zend_Search_Lucene_Analysis_TokenFilter_LowerCase());
	}
}

This of course is not very handy all the time. So, how do namespaces solve this problem?

Namespaces in php 5.3

A namespace in php can be thought of as an extra layer around (part of) your code. Every class en method name within it is unique and does not conflict with classes or methods with the same name in other namespaces.

To declare a namespace in php, use the keyword 'namespace' on the first line of your file. Your classes and methods you define below it. All code within that file will be in that namespace. Let's look at an example on how to use namespaces:

< ?php
namespace MichielvdVelde\Core;
 
class Database
{
	public function __construct()
	{
	}
}

The class Database will now reside in the namespace MichielvdVelde\Core. If you were to make another namespace, which also holds a class named Database, this would be fine.

So, how do you use classes within a namespace? This is really kind of simple. There are two method.

Method one

Add the namespace to the declaration of the class. Like this:

< ?php
require_once 'MichielvdVelde/Core.php';
 
$db = new MichielvdVelde\Core\Database();

But this method is not really an improvement over poor man's namespacing. Therefore, there is a second method.

Method two

By using the 'use' keyward, you cam import namespaces in your code. This more closely resembles namespacing as implemented in other languages such as C++ and C#.

< ?php
require_once 'MichielvdVelde/Core.php';
 
use MichielvdVelde\Core as CORE;
 
$db= new CORE\Database();

As you can see, this is more aliasing than really importing. But still, this method is very useful.

Gotcha's

Functions are also part of namespaces

When defining functions in files with the 'namespace' keyword at the top, thsey are also part of that namespace.

< ?php
namespace MichielvdVelde\Core;
 
function getDatabase()
{
}
< ?php
require_once 'MichielvdVelde/Core.php';
 
getDatabase(); // Geeft E_FATAL error: Undefined function getDatabase()
 
use MichielvdVelde\Core as CORE;
 
CORE\getDatabase(); // This does work

Autoload changes

Autoload on Windows does not use the \ very well. You may need to change your autoload function for this:

< ?php
function __autoload($className)
{
	$className = str_replace('\\', DIRECTORY_SEPARATOR, $className) . '.php';
	require $className;
}
 
$db = new MichielveVelde\Core\Database();

Also note that you need to define __autoload within the global scope. If you define it within a namespace, php won't find it. If you do want to use the autolaod function from within a namespace, use the spl_autoload_register function:

spl_autoload_register('MichielvdVelde\\Core\\Autoloader');

Conclusion

PHP 5.3 introduces support for namespaces which will be very handy in organizing and cleaning up your code. Although it may take some time for web hosters to support php 5.3, you can experiment with it by installing the latest version of XAMPP on your omputer, which has php 5.3 included.