Summary: in this tutorial, you’ll learn about PHP namespaces, how to define classes that belong to a namespace, and how to use namespaces.
Why namespaces
When your project grows in complexity, you’ll need to integrate the code from others. Sooner or later, you’ll find that your code has different classes with the same name. This problem is known as name collision.
To resolve it, you can use namespaces. PHP supported namespaces since version 5.3.
What is a namespace
It’s easier to understand namespaces by analogy to the directory structure in a filesystem.
A directory stores related files, which is similar to a namespace that groups related classes.
A directory doesn’t allow you to have two files with the same name. However, you can have files with the same names in different directories. Likewise, namespaces mimic the same principle.
By definition, namespaces provide you with a way to group related classes and help you avoid any potential name collisions.
Namespaces are not limited to group classes. They can group other identifiers, including functions, constants, variables, etc.
Set up a directory structure
First, create a project directory, e.g., store
and create a new index.php
file in the directory.
Second, create src
directory in the project directory and Model
directory in the src
directory.
Third, create a new file called Customer.php
in the Model
directory with the following code:
<?php
class Customer
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
Code language: HTML, XML (xml)
The directory looks like the following:
.
├── index.php
└── src
└── Model
└── Customer.php
Code language: plaintext (plaintext)
Define a namespace
To define a namespace, you place the namespace
keyword followed by a name at the very top of the page. The following example gives the Customer
class with a namespace Store\Model
:
<?php
namespace Store\Model;
class Customer
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
Code language: HTML, XML (xml)
- It’s customary to assign the
src
directory theStore
namespace. And you can replaceStore
with your brand name, e.g., Apple. - It’s a good practice to imitate the directory structure with the namespace to find classes more easily. For example, every class within the directory will get the namespace
Store\Model
.
Use a class that belongs to a namespace
To use a class that belongs to a namespace in the index.php
, you need to include the file and use the class:
<?php
require 'src/Model/Customer.php';
$customer = new Customer('Bob');
echo $customer->getName();
Code language: HTML, XML (xml)
If you open the index.php
, you’ll get a fatal error:
Fatal error: Uncaught Error: Class 'Customer' not found in...
Code language: JavaScript (javascript)
Since the Customer
class now is namespaced, you need to use the fully qualified name that includes the namespace like this:
<?php
require 'src/Model/Customer.php';
$customer = new Store\Model\Customer('Bob');
echo $customer->getName();
Code language: HTML, XML (xml)
Now, it should work properly.
Import a namespace
To avoid using the fully qualified names from a namespace, you can import the namespace with the use
operator like this:
<?php
require 'src/Model/Customer.php';
use Store\Model;
$customer = new Model\Customer('Bob');
echo $customer->getName();
Code language: HTML, XML (xml)
Now, you just need to prefix the class name with Model
.
Import a class from a namespace
PHP allows you to import a class from a namespace instead of importing the namespace. For example:
<?php
require 'src/Model/Customer.php';
use Store\Model\Customer;
$customer = new Customer('Bob');
echo $customer->getName();
Code language: HTML, XML (xml)
In this example, we use the use
operator to import the Customer
class from the Store\Model
namespace. Therefore, we don’t have to prefix the class name with the namespace.
Import multiple classes from a namespace
First, create a new file called Product.php
in the src/Model
directory:
<?php
namespace Store\Model;
class Product
{
}
Code language: HTML, XML (xml)
For demonstration purposes, the Product
class is empty. Now, the directory structure looks like the following:
.
├── index.php
└── src
└── Model
├── Customer.php
└── Product.php
Code language: plaintext (plaintext)
To use both Customer
and Product
classes from the index.php
, you can import them individually like before:
<?php
require 'src/Model/Customer.php';
require 'src/Model/Product.php';
use Store\Model\Customer;
use Store\Model\Product;
$customer = new Customer('Bob');
echo $customer->getName();
$product = new Product();
Code language: HTML, XML (xml)
When the number of imported classes grows, your code will become more verbose. So instead of importing each individual class, you can import all the classes using a single statement:
use namespace\{className1, className2, ...}
Code language: PHP (php)
For example:
<?php
require 'src/Model/Customer.php';
require 'src/Model/Product.php';
use Store\Model\{Customer, Product};
$customer = new Customer('Bob');
echo $customer->getName();
$product = new Product();
Code language: HTML, XML (xml)
Alias classes from a namespace
First, create a new directory called Database
under the project directory and place a new file Logger.php
in the Database
directory with the following code:
<?php
namespace Store\Database;
class Logger
{
public function log($message)
{
var_dump('Log ' . $message . ' to the database.');
}
}
Code language: HTML, XML (xml)
Second, create a new directory Utils
under the project directory and create a new Logger.php in the Utils
directory.
<?php
namespace Store\Utils;
class Logger
{
public function log($message)
{
var_dump('Log ' . $message);
}
}
Code language: HTML, XML (xml)
Now, you have two classes with the same name in different namespaces:
.
├── index.php
└── src
├── Database
│ └── Logger.php
├── Model
│ ├── Customer.php
│ └── Product.php
└── Utils
└── Logger.php
Code language: plaintext (plaintext)
Third, import Logger
classes from both namespaces Store\Utils
and Database\Logger
into the index.php
file:
<?php
require 'src/Utils/Logger.php';
require 'src/Database/Logger.php';
use Store\Utils\Logger;
use Store\Database\Logger;
Code language: HTML, XML (xml)
PHP raises the following error:
Fatal error: Cannot use Store\Database\Logger as Logger because the name is already in use in...
Code language: plaintext (plaintext)
To avoid this, you can just import the namespaces:
<?php
require 'src/Utils/Logger.php';
require 'src/Database/Logger.php';
use Store\Utils;
use Store\Database;
$loggers = [
new Utils\Logger(),
new Database\Logger()
];
Code language: HTML, XML (xml)
Or you can give a class an alias when importing it:
import namespace\className as newClassName;
Code language: JavaScript (javascript)
The following example assigns the DatabaseLogger
class an alias to the Store\Database\Logger
class:
<?php
require 'src/Utils/Logger.php';
require 'src/Database/Logger.php';
use Store\Utils\Logger;
use Store\Database\Logger as DatabaseLogger;
$loggers = [
new Logger(),
new DatabaseLogger()
];
Code language: HTML, XML (xml)
Use classes from the global namespace
To use global classes such as built-in classes or user-defined classes without a namespace, you need to precede the name of such classes with a backslash (\
).
The following example shows how to use the built-in DateTime class in the App namespace:
<?php
namespace App;
$publish_at = new \DateTime();
echo $publish_at->format('Y-m-d H:i:s');
Code language: HTML, XML (xml)
Summary
- Use a namespace to group related classes.
- Mimic the directory structure with the namespaces to make it easier to find the classes.
- Use the
use
operator to import a namespace or a class from a namespace. - Use the
as
keyword to assign a namespace or a class of a namespace an alias.