What are namespaces?
Since it’s easier to learn about the keyword “use” by knowing about “namespace”, let me explain namespace first by looking at a basic Laravel project.
There is a controller class with the name: Controller.php which is in the path: app/Http/Controllers from the project’s root directory There is also another controller class named: Controller.php, but this one is in the path: vendor/laravel/framework/src/Illuminate/Routing from the project’s root directory
You don’t need to look at the source code yet if you’re new to php because it can confuse you, instead let me explain to you the part of it that we care about and will help us understand “namespace” and “use”.
So as a matter of fact, our first controller class: app/Http/Controllers/Controller.php needs to use the Second controller class vendor/laravel/framework/src/Illuminate/Routing/Controller.php. it actually needs to extend this Class in order to have access to its content for handling some crucial routing functionalities.
So how can a class extend another class that has the same name?
class Controller extends Controller
? this will NOT work,
unless there is a way to distinguish these two classes and that’s where namespace
comes handy and the use
keyword
helps to complete the mission of, allowing the usage of; (classes; methods; interfaces and constants), with the same name, in the same scope.
now how is it done in the code? very simple! if we look at app/Http/Controllers/Controller.php source code, we can see at the top of the class
namespace is declared as: namespace App\Http\Controllers
, so this is how you give your class a namespace so it can be referenced by other classes
now this looks the same as the path to this class from the project’s root directory, with little difference and that’s the usage of “\
” instead of “/
“
(same as command prompt in windows),
but there is another difference and that’s the App with capital ‘A’ in the namespace versus ‘app’ with
Lowercase ‘a’ in the path. Also note that namespace is case-sensitive.
So namespace is a separate concept than the path, it can follow the path structure if it helps but it doesn’t have to be exact path to the class, method, interfaces or constants for example take a look at: vendor/laravel/framework/src/Illuminate/Routing/Controller.php source code,
we see at the top of the class the namespace is declared as: Illuminate\Routing
now let’s take look at the “use
” keyword,
we use, the “use
” keyword to make our class aware of a specific class or function that we want to use in our class
so we are not importing or including anything we’re just letting our class know that we will be using a specific class or
method by referencing them by their namespace
let’s take a look at app/Http/Controllers/Controller.php source code,
as you can see from the line: “use Illuminate\Routing\Controller as BaseController
”, the “use
” keyword followed by namespace
for the target class
(note that Illuminate\Routing\Controller.php and Illuminate\Routing\Controller ‘without .php extension’ are interchangeable)
we can use the “as
” keyword along with the “use
” keyword to give a specific class, method, interfaces or constants an alias which allows
app/Http/Controllers/Controller.php to extend Illuminate\Routing\Controller.php as BaseController in the line:
“class Controller extends BaseController
”.
A namespace allows you to place a bunch of code under a name and not have any naming conflicts with classes, functions and constants.
It allows your code to live in that namespace.
PHP uses the somewhat controversial character \
to show namespace levels. People got up in arms because it is also used as an escape character.
To use the namespace in PHP, use something like this at the top of your file.
namespace my\namespace;
You can find a lot more information on the official PHP documentation for namespaces.
Namespacing does for functions and classes what scope does for variables. It allows you to use the same function or class name in different parts of the same program without causing a name collision.
In simple terms, think of a namespace as a person's surname. If there are two people named "John" you can use their surnames to tell them apart.
The Scenario
Suppose you write an application that uses a function named output()
. Your output()
function takes all of the HTML code on your page and sends it to the user.
Later on your application gets bigger and you want to add new features. You add a library that allows you to generate RSS feeds. This library also uses a function named output()
to output the final feed.
When you call output()
, how does PHP know whether to use your output()
function or the RSS library's output()
function? It doesn't. Unless you're using namespaces.
Example
How do we solve having two output()
functions? Simple. We stick each output()
function in its own namespace.
That would look something like this:
namespace MyProject;
function output() {
# Output HTML page
echo 'HTML!';
}
namespace RSSLibrary;
function output(){
# Output RSS feed
echo 'RSS!';
}
Later when we want to use the different functions, we'd use:
\MyProject\output();
\RSSLibrary\output();
Or we can declare that we're in one of the namespaces and then we can just call that namespace's output()
:
namespace MyProject;
output(); # Output HTML page
\RSSLibrary\output();
No Namespaces?
If we didn't have namespaces we'd have to (potentially) change a lot of code any time we added a library, or come up with tedious prefixes to make our function names unique. With namespaces, we can avoid the headache of naming collisions when mixing third-party code with our own projects.