Share via:

PHP: Namespaces

Learn about Namespaces in PHP, and when you should be using them. A greatly simplified tutorial for OOP beginners.

42 views

Edited: 2019-09-14 11:18

Before we start, please do not feel intimidated by namespaces, if you take the time to read this article, you will probably find namespaces much easier to understand.

Namespaces are basically used to avoid conflicts in naming of classes and functions, mainly conflicts with the build-in classes in PHP, as well as conflicts with code obtained from third parties.

In other words, conflicts between your own code, and code written by others.

You can think of namespaces as being similar to directories in a file system. In the same way that two files with the same name can not exist in the same directory, two classes or functions with the same name can not exist within the same namespace.

Namespaces in PHP

By default, you are working in a "root" type of namespace, meaning if you decide to name a function trim(), it will result in a fetal error in your script, since PHP already has a build-in function named trim().

PHP Fatal error: Cannot redeclare trim() in...

Now, if instead you choose to change the namespace of your code, by writing something like this, somewhere in the top of your script:

namespace your_root_name_space;

Suddenly you will magically be able to "overwrite" PHPs build-in trim() function with your own. Just try running the below in a terminal:

namespace your_root_name_space;

function trim()
{
  echo 'Yaaah';
}

trim();

And do not worry about loosing the ability to call existing PHP functions! Only the functions you explicitly declare will be overwritten. How cool is that?!!

The same logic goes for classes, with one tiny difference. For example, PHP has a build-in class called DateTime used to work with timestamps. Normally you would use this class like this:

$date = DateTime::createFromFormat('j-M-Y', '15-Feb-2009');
echo $date->format('Y-m-d');

If you have changed the namespace, and then try to call this class, you will get an error like this:

PHP Fatal error: Uncaught Error: Class 'your_root_name_space\DateTime' not found in...
Stack trace:
#0 {main}
thrown in...

The reason for this is that PHP is now looking for the class within your namespace. To solve the problem, you have to prepend a backslash when instantiating the DateTime class:

namespace your_root_name_space;

$date = \DateTime::createFromFormat('j-M-Y', '15-Feb-2009');
echo $date->format('Y-m-d');

The output should look like:

2009-02-15

The backslash character "\" is used as a namespace separator, in a similar way it might be used as a directory separator in a file system. So, what we are in reality saying by including it before \DateTime, we are telling PHP to look for the class in the root. PHP's own root.

This is no different than how file systems work. You may also want to read about Absolute and Relative Paths

Who should use namespaces

I think everyone should use namespaces. The only excuse not to use them, is if you do not know how. There is a misconception among PHP developers, that it is not needed for small projects.

It should not be the size of your project that determines if you use OOP and namespaces, rather it should be the specific circumstances. Even your CLI scripts can benefit greatly from using OOP and namespaces in the long run.

Making use of namespaces will only make it easier for yourself as your project grows.

Best practices

To make it easier for yourself when coding, you can follow PSR best practices. I recommend you also use an autoloader to load classes. One such autoloader is the Psr4AutoloaderClass autoloader. There is an example of how to implement it in Beamtic's GitHub repository, located here, and also you can look at the official PSR autoloader examples.

I am still learning about coding standards myself, as I am trying to simplify and improve my code as much as possible. It is a process, and you just got to accept that you might never finish improving and maintaining your code, let alone improving your coding skills.

Using an autoloader simply allows you to instantiate the class directly, without first having to include a bunch of class files. The result is you spend less time thinking about including files, and more time coding. This is maybe a very small optimization. But, even small improvements will help you in the long run. I.e.:

// require 'lib/some_class/some.class.php'; 
$MyObject = new your_root_name_space\lib\some_class\some_class();

The inclusion line is commented out, as it is no longer needed with the autoloader.

Namespaces and directories

It is generally good practice to map your namespaces to a directory structure, but it is not required.

This means, if the namespace in a class is: your_root_name_space\lib\some_class\ the file system location of the class file should be: your_root_name_space/lib/some_class/some_class.php

According to the PSR coding standards, the PHP class name should also match the name of the file. This enables automatic loading of the file with the PSR autoloader.

Comments