Namespaces have been around for quite a while in Object Oriented programming with languages such Java. Basically, for those of you who have not used them, it means that you can create a context or package for a set of variables, functions and classes to prevent same named objects from different packages to conflict.

<?php
/* PHP Namespace sample */
namespace Project::Sample;

class Foo {
  function bar () {
    echo "Test namespace function";
  }
}

// since Project::Sample is the current namespace
$foo = new Foo();

// or using the full namespace
$foo = new Project::Sample::Foo();

// or using the use keyword
use Project::Sample as Sample

$foo = new Sample::Foo();

$foo->bar(); // Prints: Test namespace function
?>

Currently, the only solution is to prefix objects within a package or project with the project name. This method works, but it creates large names and repetition.

For example, say you have a blog project that you named MyBlog and a company named MyCompany, the following code could be a sample of the article class.

<?php
class MyCompany_MyBlog_Article {
  private $title;

  public function setTitle($title) {
    $this->title = $title;
  }

  public function getTitle() {
    return $this->title;
  }
}
?>

This currently works, yes. The problem is that any time you want to call the Article class created above you have to use MyBlog_Article. Namespaces solve this problem.

Creating namespaces

Here is what the above code would look like using namespaces instead.

<?php
namespace MyCompany::MyBlog;

class Article {
  private $title;

  public function setTitle($title) {
    $this->title = $title;
  }

  public function getTitle() {
    return $this->title;
  }
}
?>

At a first glance, there is little difference in the code. In fact, the second sample has more code because of the namespace keyword. Namespaces do provide improvement though. First, any object that is created after the namespace call will be placed under that namespace. So you can create multiple objects without including MyBlog for each one. Additionally, if you were to decide to change the name of the project or package, all you have to do is change the namespace call. All the other objects would fall under the new naming. Lastly, calling the objects becomes a lot simpler, as you will not have to directly reference the full name of the object including the namespace every time you need it.

Using namespaces

Lets look at how we could use the above article class with namespaces.

<?php
require ("/path/to/class/mycompany.myblog.article.php");
use MyCompany::MyBlog;

$article = new MyBlog::Article();
$article->setTitle(‘Sample Title’);
echo $article->getTitle(); // Prints: Sample Title
?>

Now this is where the beauty of namespaces comes in to play. The use keyword sets the namespace locally so you do not have to call objects within it with the full namespace, so instead of using MyCompany::MyBlog::Article you can simply use MyBlog::Article as is shown in the example above. You can always use the article object without the use keyword.

<?php
require ("/path/to/class/mycompany.myblog.article.php");

$article = new MyCompany::MyBlog::Article();
?>

Multiple Namespaces and Aliases

A great feature of namespaces is being able to use multiple namespaces at once. Say you are writing a plugin to write to multiple blogs at once (I have no clue why you would need one), with namespaces you would not have conflicting object names to deal with. Lets take a look at using the objects MyCompany::MyBlog::Article and OtherBlog::Article.

<?php
require ("/path/to/class/mycompany.myblog.article.php");
require ("/path/to/class/otherblog.article.php");

use MyCompany::MyBlog as My;
use OtherBlog as Other;

$myarticle = new My::Article();
$otherarticle = new Other::Article();
// …
?>

Using as after the use keyword will create an alias of the namespace to make it easier to use.

Namespace Constants

You can define namespace constats using the the const keyword within a namespace.

<?php
namespace MyCompany::MyBlog;

const VERSION = ‘0.1.1′;

echo MyCompany::MyBlog::VERSION; // Prints: 0.1.1
?>

You can also call constants using namespace aliases created with the use keyword. You can also call class constants the same way.

<?php
namespace MyCompany::MyBlog;

class Article {
  const VERSION = ‘0.1.1′;
}

echo MyCompany::MyBlog::Article::VERSION; // Prints: 0.1.1
?>

Autoloading namespaces

Another great feature of namespaces is the autoload support. When calling a class by its namespace, the full class name, including namespaces, will be passed to the __autoload function, even when using a namespace alias.

<?php
function __autoload($name) {
  $name = strtolower($name);
  $name = str_replace(‘::’, ‘.’, $name);
  require_once $name . ‘.php’;
}

use MyCompany::MyBlog as Blog;

$article = new Blog::Article();
?>

One issue that does arise with namespaces is being able to call a global function from within a namespace. To call a global function you would need to prefix an empty scope operator (::).

<?php
namespace package;

function test() {
  echo "Calling the packaged test function";
}

test(); // Prints: Calling the packaged test function

::test(); // Prints: Calling the global test function
?>

<?php
function test() {
  echo "Calling the global test function";
}

require(‘package.php’);
?>

If you want to play around with this yourself you can grab a snapshot of PHP 5.3 from http://snaps.php.net/ (You can even get PHP 6 from there).

Now, all we have to do is wait until PHP 5.3 is stable and released. Since 5.3 is just a minor revision number most hosting providers would be more willing to update than if it was PHP 6. Therefore, namespaces support will take less time to be globally supported. This is very exciting news.