7 minutes to read, 1.95K views since 2016.11.06

Namespaces

Short history

Did you ever see the old-style php libs with classes like SomeLib_That_Can_Do_Something? I've had. And that was the time when php didn't support namespaces (before PHP 5.3). Why did people name their classes in such way? If you think that in such way they wanted to put in class name as much as possible information that class can do - you're wrong. People used such names to avoid names overriding.

For example i wrote a library called chat and the main class is Chat. Someone want to use my library but noticed he already have such class, his application is big and many other parts make use of it. The only way to use my library for him - to change the name of my class everywhere its used in my lib. Sounds pretty awful, yeah. And yes, its terrible. At least to modify external library, even if its only the class names;

To avoid such situations, people started to use such long names for classes, where at the begining was name of the vendor or name of the product followed by some architectural parts finishing with actual name of the class. That was awfull to - you needed to write such long class names in your programs but it worked!

In June 2009 guys from Zend thought that they're fed up with such long names and implemented namespaces in php 5.3. There was a long time before they become the number one part of each application that deserves your attention.

It took some time for me, computer science student in that early 201Xs to understand what the namespaces about which everybody wrote want from me.

What are the namespaces

Namespaces as for me are the part of the code that have its own visibility enclosed. Or simplify - names of classes in each namespaces are only visible to this namespace. This means you can have same named classes but they should be in different namespace. For example :

<?php 

namespace Catchmetech;

class Loader {

}

namespace Blog;

class Loader {

}

Its a working php 5.3+ code which declares two classes: \Catchmetech\Loader and \Blog\Loader, and we can use them only by saying what exactly class we want to use :

$loader = new \Catchmetech\Loader();

When we try to create instance of simply Loader:

new Loader();

php would say that such class not exists. And that's right, because there is no \Loader class in \ (root) namespace. Lets consider a namespace as the part of class's name, it would be easier to understand them.

Whats the difference

You would ask me, so what's the difference ? Why using \Catchmetech\Loader is better that Catchmetech_Loader? In the second variant there is no disgusting slashes, why i must use namespace instead?

The answer is simple - php has few features concerning namespaces.

  • you can use namespaces to ommit actually namespace in class name:

    <?php
    
    use Catchmetech\Loader; // this statement says to script that `Loader` is a class  Catchmetech\Loader
    
    $loader = new Loader(); // this is ok now

    If you're familiar with c++ use statement is analog of their using namespace. In java its analog of import statement.

  • you can give aliases to classes when going to use them:

    <?php
    
    use Catchmetech\Loader as Downloader; // Now Downloader is the name for Loader class
    
    $loader = new Downloader(); // this is ok

    This is the most helpfull feature for situation when you have two different classes with the same names. You can rename one of them when declaring namespaces usage

  • In PHP 7 you can group the use statements (you can't import whole namespace like in java: import org.catchmetech.*;)

     <?php 
    
     use Catchmetech\{Loader,Logger as MyLogger}; // use two class from namespace
    
     $logger = new MyLogger(); // its actually instance of \Catchmetech\Logger class

There is analogs of namespace in other languages as i admitted early: packages in java, also namespaces in c++, packages in golang and others.

Namespaces should be declared on the top of the file:

<?php 

namespace Catchmetech;

use AnotherNamespace\Model;

$model = new Model();

And not in the reverse order (next is the syntax error):

 <?php 

use AnotherNamespace\Model;
namespace Catchmetech; // that's error

$model = new Model(); 

You can use namespaces inside other namespaces as showed in example above, or use it in root namespace (when it's not set with namespace X; it means root):

<?php 

// this code inside the root \ namespace

use AnotherNamespace\Model;

$model = new Model(); // its ok

You can use nested namespaces like Catchmetech\Libraries or even Catchmetech\Core\Libraries:

<?php 

namespace Catchmetech\Libraries; // it's not obligated to use starting slash in namespace declaration 

use Catchmetech\Core\Library; // this `imports` Library class from another namespace to \Catchmetech\Libraries namespace (current);

class ZipLibrary extends Library {

}

Getting current namespace name

PHP provide predefined constant __NAMESPACE__ which holds current namespace name:

<?php 

namespace Catchmetech\InternalNS;

echo __NAMESPACE__; // \Catchmetech\InternalNS

Some drawbacks

Namespace system in php was very progressive back in 2009. But there are few problems that preventing it to be ideally thing:

  • Before php 5.6 you can't use function and constants from another namespaces:

    <?php
    
    namespace Catchmetech;
    
    const MyConst = 10; // it's not visible from anywhere outside this namespace
    
    function AddTwoInts($a,$b) { // its not visible too
      return $a+$b;
    }

    there is no possibility to use MyConst and AddTwoInts outside the Catchmetech namespace.

    In PHP 5.6 and higher you can use functions and constants as well:

    <?php
    
    use function Catchmetech\AddTwoPoints;
    use const Catchmetech\MyConst;
    
    // ...
  • As mentioned before - there is no way to group use statements before PHP 7.
  • Using everything from namespace as analog to Namespace.* is not possible at all

Namespaces are great possibility to separate your code, when it goes through the very big projects they literally saves you. Nevertheless its two lines program or thouthand files project use them!

Read next article Autoloading in course Basic PHP