Namespaces
Namespaces in PHP are similar to organizing files in your computer using different folders. Let's say you have a lot of files (documents, images, videos, etc.); you'd organize them into different folders based on their types or purposes to make things less cluttered and easier to find.
In PHP, a namespace is like a folder. It's a way to group related PHP classes, functions, and constants together.
Why use namespaces?
Developers who create libraries or applications frequently encounter challenges in making classes and functions reusable. This is where namespaces come in handy to address these issues. For instance:
- Namespaces safeguard against name overlap between our own codes and existing PHP or third-party classes, functions, or constants. They also do this for the functions and constants that we incorporate into our own code.
- They eliminate the necessity for excessively long names by permitting the use of aliases or abbreviated names, making our code more readable.
Syntax
Creating a namespace in PHP is pretty straightforward. You use the namespace
keyword at the top of your PHP file. Here's an example:
<?php
namespace MyNamespace;
In this example, we've created a namespace called MyNamespace
. The following should be considered when defining a namespace.
- Namespaces are case-insensitive. So, internal PHP namespaces like
PHP\Classes
should not be used for user-defined spaces. - Always define namespaces at the beginning of your script. This way, all functions, classes, or constants used in that script automatically fall under that namespace.
- Use the
namespace
keyword to declare namespaces.
Creating a namespace
In our namespace, we can add classes, functions, or constants. Here's an example of a class in the MyNamespace
namespace.
namespace MyNamespace;
class Hello {
public function __construct() {
echo "Hello, world!";
}
}
Now, whenever you want to call this hello()
function from outside of MyNamespace
, you would have to use the namespace like so:
new MyNamespace\Hello(); // this will output "Hello, world!"
You can think of MyNamespace
as a folder and Hello
as a file inside that folder. Just like how you need to specify the folder's name to find a file, you need to specify MyNamespace
to find the Hello
Class.
Remember, the namespace declaration must be the first thing in your PHP file, right after the <?php
opening tag. It can't be preceded by any HTML or other PHP code. The only exception to this rule is adding the declare()
statement with support for strict typing like so:
declare(strict_types=1);
namespace MyNamespace;
Sub-namespaces
We can take things a step further by using sub-namespaces. Sub-namespaces in PHP are like sub-folders on a computer. Just like you can have folders within folders to organize your files even further, you can have namespaces within namespaces to better organize your code.
For example, let's say you have a school project. You create a main folder (namespace) named "SchoolProject". Inside it, you have sub-folders (sub-namespaces) like "Math", "Science", "Art", etc.
In PHP, creating a sub-namespace would look something like this:
<?php
namespace SchoolProject\Math;
Here, SchoolProject
is the main namespace, and Math
is the sub-namespace.
Using a namespace
Let's look at how we can use namespaces. Adding a class to a namespace makes things slightly different than how you would normally write code.
Imagine we had a file called mylib.php
with the following code:
namespace App\Code;
class Customer {
public function __construct() {
echo "Customer class";
}
}
// define a function
function bar() {
echo "I am bar";
}
// define a constant
const BAZ = 50;
We've defined a class, function, and constant from within the App\Code
namespace. Any code you write after declaring a namespace from within the same file gets placed under that namespace.
Afterward, let's say we had a file called app.php
with the following code:
require "mylib.php";
// instantiate the Customer class
$obj = new \App\Code\Customer();
// call the function
echo \App\Code\bar();
// display the constant
echo \App\Code\BAZ;
The first step is to include the mylib.php
file. In this example, we're using the require
statement to do so.
After importing the file, the Customer
class can be instantiated by typing the full namespace followed by the class name. We must use new \App\Code\Customer()
.
The app.php
is not assigned any namespace. Files not assigned a namespace are placed in the global namespace. You can't access the Customer
class without a namespace reference. Note that you can access the Customer
class from inside the App\Code
namespace without the fully qualified name.
If namespaces aren't specified, classes, functions, and constants exist in a global space and behave as they did prior to the introduction of namespace support.
Namespaces are required
You must create the class with the full namespace path: \App\Code\Customer
. You cannot use Customer()
like you normally would. Classes defined in a namespace must be accessed with the namespace. Otherwise, you will encounter a fatal error.
Importing a class from a namespace
Typing out the entire namespace to reference class can be annoying. Luckily, PHP offers the use
keyword to resolve this issue.
The use
keyword is used to import classes, interfaces, functions, and constants from namespaces. It helps to make your code cleaner and easier to read, especially when you're working with long namespace paths.
Think of it as a shortcut. If you're frequently using a class from a namespace, you don't want to type the full namespace path every time. Instead, you can create a shortcut at the beginning of your file with the use keyword.
We can revise the app.php
file to the following:
use App\Code;
require "mylib.php";
// instantiate the Customer class
$obj = new \Code\Customer();
// call the function
echo \Code\bar();
// display the constant
echo \Code\BAZ;
In the above example, we've imported the App\Code
namespace. Now, you just need to add the Code
prefix when you call namespaced items, and they'll automatically be converted into fully qualified names.
This makes our code easier to read and write. Plus, if the namespace path changes in the future, we only have to update it in one place - where we created the shortcut with the use
keyword.
Importing multiple classes
What if we need to import multiple classes? For example, let's say we had a file called Product.php
with the following code:
namespace App\Code;
class Product
{
}
It's perfectly acceptable to define multiple classes with the same namespace.
Next, we can import the classes like so:
require 'mylib.php';
require 'Product.php';
use App\Code\Customer;
use App\Code\Product;
$customer = new Customer();
Similar to before, we're including the class and then importing both classes with the use
keyword. However, we're directly referencing the class names from within the use
statement. We're not limited to grabbing an entire namespace. If we're interested in grabbing a specific class, we can do so by typing the full namespace and class name.
In addition, if multiple classes are imported from the same namespace, we can use the following syntax:
use namespace\{className1, className2, ...}
So, we can update our code to the following:
require 'mylib.php';
require 'Product.php';
use App\Code\{Customer, Product};
$customer = new Customer();
Namespace aliases
A namespace alias in PHP is like a nickname you can give to a namespace or class when you import it. This is useful when the original namespace or class name is very long or if you want to use two classes with the same name from different namespaces.
You create a namespace alias with the use
keyword, followed by as
and the alias you want to use.
use namespace\classname as classNameAlias
In our case, we can use an alias for the Product
class like so:
use App\Code\Product as Service;
new Service();
Global classes from within a namespace
If you want to use global classes like built-in classes or those you've defined without a namespace, you should start the class name with a backslash (\
).
Here's an example of how to use the built-in DateTime
class in the App
namespace:
namespace App;
$publish_at = new \DateTime();
echo $publish_at->format('Y-m-d H:i:s');
In this example, we're using the global DateTime
class within the App
namespace. We add a backslash before DateTime
to tell PHP that it's a global class.
Key Takeaways
- Namespaces help to organize your code and group related classes, functions, and constants together, much like folders in a computer.
- A namespace is declared using the
namespace
keyword and must be the first statement in a PHP file. - You can further organize your code with sub-namespaces, which are like sub-folders within a namespace.
- The
use
keyword is used to import classes, functions, or constants from a namespace into your current script. It can simplify your code and make it more readable. - You can use the
use
keyword with as to create an alias (or nickname) for a namespace or class, which can make your code easier to read and write. - If you want to use global classes (like built-in PHP classes) within a namespace, you need to precede the class name with a backslash (
\
).