Namespaces allow you to have multiple classes with the same name.

Explanations

Explanation 1

Assume that we have a variable named $title in the global scope of a PHP script. Inside a function, we have another variable with the same name $title , and we assign and change values of it within the function. But, the global variable remains unchanged. This is variable scope. In the same way, classes can be namespaced to give it scope.

Explanation 2

Assume that you are creating an open-source PHP library to send emails and you share that with the developer community. Your library has a class named Email . Then, a developer downloads your library. But, if he already had a class called Email , Name Collision occurs. You will need to rename those classes or use a smarter solution: Namespaces.

Explanation 3 - The Simplest

Two people can be named "Jack". We can separate them by their surname. In the same way, two classes can have the same name. We can separate them by namespacing.

What can namespaces do?

Namespaces can prevent name collision

Namespaces can make our code more organized

Why Namespaces in PHP?

In PHP, you cannot have two classes with the same name. If you need two classes to handle your blog users and app users, you will need to name those: Blog_User and App_User . But, those prefixes are hard to manage.

Namespaces can be used to simplify the process and make it more organized. Namespaces give you more control.

Namespaces and File Structure

The concept of defining and calling namespaces is similar to the normal file structure in our operating systems.

Think namespaces as folders and files as classes.

The /lib/math folder can have multiple files in it, numbers.php , calculus.php and so on. But, no multiple files with the same name.

folder can have multiple files in it, , and so on. But, no multiple files with the same name. To access numbers.php from the calculus.php file, you can directly refer to numbers.php

from the file, you can directly refer to The /lib/physics folder can also have multiple files, mechanics.php , electromagnetism.php and more. Also, you can have numbers.php in /lib/physics even it exists in the /lib/math folder.

folder can also have multiple files, , and more. Also, you can have in even it exists in the folder. Inside the physics folder, if you use numbers.php directly it will refer to /lib/physics/numbers.php

directly it will refer to Inside the physics folder, if you needed to refer the numbers.php which exists in the /lib/math folder, you will need to use /lib/math/numbers.php

Namespaces work in the same way.

Global Namespace

When you declare a class (or function or constant) without a namespace it can be called "an item in the global namespace".

How to Define Namespaces?

The namespace keyword followed by the namespace name is used to declare a namespace in PHP.

<?php namespace MyApp;

Namespace name should be a valid PHP identifier. Namespace declaration should be the first thing in a PHP file. (with exception of declare keyword).

Declaring PHP Namespaces

Any valid PHP code can be in a namespace, but only classes, interfaces, constants, and functions are affected. Even it is possible to have multiple namespaces in the same file, it is not recommended.

Creating and Accessing Namespaced Classes

One special thing to remember throughout this tutorial: PHP is always relative to the current namespace.

If we add the namespace declaration at the top of a PHP file, all the classes, functions and constants will be items of that namespace.

Items of Namespaces

Let's create a file named Math.php and add the following code.

Math.php

<?php namespace Math; function add($a, $b) { return $a + $b; } const PI = 3.14; class Geometry { static function getCircleArea($radius) { return PI * $radius ** 2; } }

First, we declare the namespace. (So, all the classes, interfaces, constants and function below it will be items of that namespace)

Then, we declared a normal function.

Then, a class constant.

Then, a class.

Here comes the interesting part. Let's create another file called usage.php and access the above Math namespace's items (functions, constants, and classes).

usage.php

<?php // includes the Math.php file // It's like you had all the code of Math.php written here include_once 'Math.php'; echo Math\add(2,3); // 5 echo Math\PI; // 3.14 echo Math\Geometry::getCircleArea(10); // 314.15

The \ character is used to go a level down in namespaces.

Sub-Namespaces

In an operating system, folders can contain folders. In the same way, namespaces can contain namespaces. They are called sub-namespaces.

<?php namespace Math\Geometry; // ... your geometry classes

Hereafter, we will only be using classes in namespaces. (No more functions and constants as this is the OOP section in this tutorial)

Recommended Structure for Namespaces

We will learn all the recommendations for Object-Oriented programming in PHP in a later chapter. But, here we will learn how to structure your namespaces as it is really important to know.

It is recommended to map namespaces with local directories of your computer. See this example:

Assume you have your project in the /var/www folder.

folder. To make it clean, we will have our PHP class files in /var/www/src folder.

folder. Each namespace will have a directory named as the same name as the namespace. (Match the letter case)

So, the folder representing Math namespace will be /var/www/src/Math .

namespace will be . Each class should be in a single PHP file (with .php ) and one PHP class file should only contain one class definition.

Ex: Math\Addition => /var/www/src/Math/Addition.php

) and one PHP class file should only contain one class definition. Ex: => Sub-Namespaces should have their own folders to contain classes. For example, the classes of Math\Geometry sub-namespace should be in the folder /var/www/src/Math/Geometry

These are recommendations. Not rules. You can follow them if you like.

Example - Math Namespace

Let's understand more by doing. In this example, we will be creating a namespace named Math and add sub-namespaces, classes into it. Here's the structure.

Main namespace: Math

One Subnamespaces: Math\Geometry (To handle geometry)

(To handle geometry) Two Classes: Math\Constants (To save frequently used constants) and Math\Geometry\Circle (To handle circle)

Here's the final structure of our project.

/src /Math /Geometry Circle.php Constants.php

Math/Constants.php

<?php namespace Math; class Constants { const PI = 3.14159; }

Math/Geometry/Circle.php

<?php namespace Math\Geometry; class Circle { public $radius; public function __construct($radius) { $this -> radius = $radius; } public function getDiameter() { return $this -> radius * 2; } public function getArea() { // (pi)(r^2) return \Math\Constants::PI * $this -> radius ** 2; } public function getCircumference() { // 2(pi)(r) return 2 * \Math\Constants::PI * $this -> radius; } }

In Circle.php , we used \Math\Constants::PI to refer the constant in Constants.php file. This is because PHP is always relative to the current namespace. When a namespace starts with a backslash ( \ ), the name will be resolved relative to the global namespace. If we used Constants::PI in Circle.php, it would refer \Math\Geometry\Constants::PI .

in Circle.php, it would refer . If we used Math\Constants::PI (without starting backslash) in Circle.php, it it will refer to \Math\Geometry\Math\Constants::PI

Simply, class names are relative to the current namespace. Starting backslash ( \ ) is used to go back to the start. Relative namespaces aren't currently supported in PHP. ( ../Constants::PI is not supported)

Finally, let's use our classes in index.php (which should be in the root folder of your project)

<?php include_once 'src/Math/Constants.php'; include_once 'src/Math/Geometry/Circle.php'; $circle = new Math\Geometry\Circle(10); echo $circle -> getDiameter(); // 20 echo $circle -> getArea(); // 314.159 echo $circle -> getCircumference(); // 62.8318

First, We included the class files.

Then, used the Math\Geometry\Circle class and its methods.

Important to note that index.php is in the global namespaces as it is not in any namespace.

Using "use" in Namespaces to Import

The use keyword can be used to import a class to the current scope.

If you add the following code in your index.php, Math\Geometry\Circle class will be imported to the current scope.

<?php use Math\Geometry\Circle; $circle = new Circle(10); // as Circle class is now in this namespace

You can import both namespaces and classes

<?php use Math\Geometry; // importing an namespace use Math\Geometry\Circle; // importing a class

You can nickname (or alias) the imports

There are two places to use nicknames (or aliases) for importing classes.

When you already have a class named the same name as the importing class

When you need a more convenient (or easy) name for the importing class

The as keyword is used for nicknaming.

<?php use Math\Geometry\Circle as Circ; $circle = new Circ(10);

Changing the previous example

Let's change our index.php of the previous example adding use statements to import the class.

<?php // ... import statements use Math\Geometry\Circle; $circle = new Circle(10); // ... calling methods

As we did not have an as keyword, the imported class could be referred to using Circle . We can also import the Circle class with a nickname.

<?php use Math\Geometry\Circle as C; $circle = new C(10);

Wait! It is not a good practice to use names like C . Always use descriptive names.

Here's a task for you: Use use as in the Circle.php and replace the \Math\Constants::PI with a short name.

Organizing Code with Namespaces

One of the main uses of namespaces is for organizing codes. Let's assume that you are creating an open-source library.

You will need to prevent name collision. So, it's better to add all the classes into a namespace. (Named as your name or library's name).

Group similar classes into a subnamespace.

Use the folder structure which we learned early correctly.

Conclusion

In this tutorial, we learned what are namespaces, why do we use them, and how to use them. Namespaces make your project more structured and easy to manage when used correctly. You can use your own way to do that, but follow the recommendations as most of the developers do that.