A namespace is a space that organizes classes, interfaces, and functions and prevents collisions between them.
As your project grows, or when you start using third-party libraries with Composer, a serious problem arises: Name conflicts.
Imagine you create a class called User. Then you install an authentication library that also has a class called User.
What does PHP do? Fatal Error. There cannot be two classes with the same name.
Namespaces solve this. They work just like folders in your operating system: you can have photos/file.txt and work/file.txt. They have the same name, but they live in different “virtual directories”.
Defining a namespace
To place your code inside a “virtual folder”, you use the namespace keyword on the first line of your PHP file (after <?php).
File: MyProject/Models/User.php
<?php
namespace MyProject\Models;
class User {
public function greet() {
return "I am the user from YOUR project.";
}
}Now, the real, full name of that class is no longer User. It is:
\MyProject\Models\User
Importing with use
If you want to use that class in another file, you have two options:
Option A: The full path (Inconvenient) You have to write the “full name and surname” every time.
$user = new \MyProject\Models\User();Option B: Import with use (Professional)
At the beginning of the file, you indicate which classes you will use. This way, you only write the short name afterwards.
<?php
// Import the class once
use MyProject\Models\User;
// Now we use it as if it were right here
$user = new User();
echo $user->greet();Resolving conflicts (aliases)
What happens if you need to use TWO classes with the same name (e.g., your User and the User from a library)? We use as to give it a nickname.
<?php
use MyProject\Models\User as MyUser;
use ExternalLibrary\Auth\User as AuthUser;
$me = new MyUser(); // Instantiates your class
$them = new AuthUser(); // Instantiates the library classThe global root (\)
When you are inside a namespace (e.g., namespace MyApp;), PHP assumes that everything you call belongs to that namespace.
If you try to use a native PHP class (like DateTime, Exception, or PDO) without preceding it with a backslash, PHP will look for \MyApp\DateTime and fail.
To access global PHP classes from within a namespace, we prepend \:
namespace MyApp\Controllers;
class Report {
public function create() {
// WRONG: It will look for \MyApp\Controllers\DateTime
// $date = new DateTime();
// CORRECT: The initial backslash means "look in the global root of PHP"
$date = new \DateTime();
}
}