Namespacing in PHP

In PHP adaptation 5.3 another element known as namespacing was added to the language. Numerous present day language as of now had this component for quite a while, yet PHP was somewhat late to the scene. None the less, every new component has a reason for existing, how about we discover why PHP namespaces can advantage our application.

In PHP you can’t have two classes that have the same name. They must be extraordinary. The issue with this limitation is that on the off chance that you are utilizing an outsider library which has a class named User, then you can’t make your own particular class likewise called User. This is a genuine disgrace, on the grounds that that is a really helpful class name right?

PHP namespaces permit us to evade this issue, truth be told we can have the same number of User classes as we like. That as well as we can utilize namespaces to contain our comparative code into flawless little bundles, or even to show possession.

How about we investigate a typical class. Yes… I know you have utilized them some time recently. Simply believe me on this one alright?

Global Namespace

Here’s a really simple class.

<?php

// app/models/Eddard.php

class Eddard
{

}

There’s nothing special to it, if we want to use it then we can do this.

<?php

// app/routes.php

$eddard = new Eddard();

Simple Namespacing

Let’s create another class alongside the original, global Eddard.

<?php
namespace Stark;

// app/models/another.php

class Eddard
{

}

Here we have another Eddard class, with one minor change. The addition of the namespace directive. The line namespace Stark; informs PHP that everything we do is relative to the Stark namespace. It also means that any classes created within this file will live inside the ‘Stark’ namespace.

Now, when we try to use the ‘Stark’ class once again.

<?php

// app/routes.php

$eddard = new Eddard();

Once again, we get an instance of the first class we created in the last section. Not the one within the ‘Stark’ namespace. Let’s try to create an instance of the ‘Eddard’ within the ‘Stark’ namespace.

<?php

// app/routes.php

$eddard = new Stark\Eddard();

We can instantiate a class within a namespace, by prefixing it with the name of the namespace, and separating the two with a backward (\) slash. Now we have an instance of the ‘Eddard’ class within the ‘Stark’ namespace. Aren’t we magical?!

You should know that namespaces can have as many levels of hierarchy as they need to. For example:

This\Namespace\And\Class\Combination\Is\Silly\But\Works

Theory of Relativity

Remember how I told you that PHP always reacts relative to the current namespace. Well let’s take a look at this in action.

<?php

namespace Stark;

// app/routes.php

$eddard = new Eddard();

By adding the namespace directive to the instantiation example, we have moved the execution of the PHP script into the ‘Stark’ namespace. Now because we are inside the same namespace as the one we put ‘Eddard’ into, this time we receive the namespaced ‘Eddard’ class. See how it’s all relative?

Now that we have changed namespace, we have created a little problem. Can you guess what it is? How do we instantiate the original ‘Eddard’ class? The one not in the namespace.

Fortunately, PHP has a trick for referring to classes that are located within the global namespace, we simply prefix them with a backward (\) slash.

<?php

// app/routes.php

$eddard = new \Eddard();

With the leading backward (\) slash, PHP knows that we are referring to the ‘Eddard’ in the global namespace, and instantiates that one.

Use your imagine a little, like how Barney showed you. Imagine that we have another namespaced class called Tully\Edmure. Now we want to use this class from within the ‘Stark’ framework. How do we do that?

<?php

namespace Stark;

// app/routes.php

$edmure = new \Tully\Edmure();

Again, we need the prefixing backward slash to bring us back to the global namespace, before instantiating a class from the ‘Tully’ namespace.

It could get tiring, referring to classes within other namespaces by their full hierarchy each time. Luckily, there’s a nice little shortcut we can use. Let’s see it in action.

<?php

namespace Stark;

use Tully\Edmure;

// app/routes.php

$edmure = new Edmure();

Using the use statement, we can bring one class from another namespace, into the current namespace. Allowing us to instantiate it by name only. Now don’t ask me why it doesn’t need the backward slash prefix, because I just don’t know. This is the only exception that I know of. Sorry about that! You can prefix it with a slash if you want to though, you just don’t need to.

To make up for that horrible inconsistency, let me show you another neat trick. We can give our imported classes little nicknames, like we used to in the PHP playground. Let me show you.

<?php

namespace Stark;

use Tully\Brynden as Blackfish;

// app/routes.php

$brynden = new Blackfish();

By using the ‘as` keyword, we have given our ‘Tully/Brynden’ class the ‘Blackfish’ nickname, allowing us to use the new nickname to identify it within the current namespace. Neat trick right? It’s also really handy if you need to use two similarly named classes within the same namespace, for example:

<?php

namespace Targaryen;

use Dothraki\Daenerys as Khaleesi;

// app/routes.php

class Daenerys
{

}

// Targaryen\Daenerys
$daenerys = new Daenerys();

// Dothraki\Daenerys
$khaleesi = new Khaleesi();

By giving the ‘Daenerys’ within the ‘Dothraki’ namespace a nickname of ‘Khaleesi’, we are able to use two ‘Daenerys’ classes by name only. Handy right? The game is all about avoiding conflicts, and grouping things by purpose or faction.

You can use as many classes as you need to.

<?php

namespace Targaryen;

use Dothraki\Daenerys;
use Stark\Eddard;
use Lannister\Tyrion;
use Snow\Jon as Bastard;

Structure

Namespaces aren’t just about avoiding conflicts, we can also use them for organisation, and for ownership. Let me explain with another example.

Let’s say I want to create an open source library. I’d love for others to use my code, it would be great! The trouble is, I don’t want to cause any problematic class name conflicts for the person using my code. That would be terribly inconvenient. Here’s how I can avoid causing hassle for the wonderful, open source embracing, individual.

Dayle\Blog\Content\Post
Dayle\Blog\Content\Page
Dayle\Blog\Tag

Here we have used my name, to show that I created the original code, and to separate my code from that of the person using my library. Inside the base namespace, I have created a number of sub-namespaces to organise my application by its internal structure.

In the composer section, you will learn how to use namespaces to simplify the act of loading class definitions. I strongly suggest you take a look at this useful mechanism.

Limitations

In truth, I feel a little guilty for calling this sub-heading ‘Limitations’. What I’m about to talk about isn’t really a bug.

You see, in other languages, namespaces are implemented in a similar way, and those other languages provide an additional feature when interacting with namespaces.

In Java for example, you are able to import a number of classes into the current namespace by using the import statement with a wildcard. In Java, ‘import’ is equivelent to ‘use’, and it uses dots to separate the nested namespaces (or packages). Here’s an example.

import dayle.blog.*;

This would import all of the classes that are located within the ‘dayle.blog’ package.

In PHP you can’t do that. You have to import each class individually. Sorry. Actually, why am I saying sorry? Go and complain to the PHP internals team instead, only, go gentle. They have given us a lot of cool stuff recently.

Here’s a neat trick you can use however. Imagine that we have this namespace and class structure, as in the previous example.

Dayle\Blog\Content\Post
Dayle\Blog\Content\Page
Dayle\Blog\Tag

We can give a sub-namespace a nickname, to use it’s child classes. Here’s an example:

<?php

namespace Baratheon;

use Dayle\Blog as Cms;

// app/routes.php

$post = new Cms\Content\Post;
$page = new Cms\Content\Page;
$tag  = new Cms\Tag;

This should prove useful if you need to use many classes within the same namespace. Enjoy!

About the author

PHP | MVC | Codeignitor | Zend | Yii | Smarty | Android | Laravel Expert Senior Software Developer.I love my job and feel happy to working on new ideas and technologies.

Leave a Comment

Comment (required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Name (required)
Email (required)