PHP Namespaces: Avoid use

Main Thread 1 min read

use breaks the fundamental aspects of PHP namespaces. Avoid use.

Oh, you want to know why? Fine. Keep reading.

Let's review the fundamental aspects of PHP namespaces as stated in the PHP Docs Namespace Overview:

namespaces are designed to solve two problems that authors of libraries and applications encounter when creating re-usable code elements

So namespaces focus on re-usable code elements. Let's look at the two problems:

  1. Name collisions between code you create, and internal PHP classes/functions/constants or third-party classes/functions/constants.
  2. Ability to alias (or shorten) Extra_Long_Names designed to alleviate the first problem, improving readability of source code.

namespace solves problem #1. use solves problem #2. But things can get circular. use can introduce name collisions and confusion. Which respectively reintroduces problem #1 and is the opposite of improving readability.

Consider the following namespaces and classes:

1// MyApp/Service.php
2namespace MyApp;
3 
4class Service {
5 public function method() {
6 echo __NAMESPACE__ . '\Service';
7 }
8}
9 
10// MyApp/ComponentA/Service.php
11namespace MyApp\ComponentA;
12 
13class Service {
14 public function method() {
15 echo __NAMESPACE__ . '\Service';
16 }
17}

A Controller class with use:

1// MyApp/Controller.php
2namespace MyApp;
3 
4use MyApp\ComponentA\Service;
5 
6class Controller {
7 public function output() {
8 $service = new Service();
9 $service->method();
10 }
11}

Which Service class is created? MyApp\Service or MyApp\ComponentA\Service?

It may be straightfoward when the entire codebase fits within your screen. But consider a larger codebase. What if you refactored output() into another class? It all depends on the use statement. Meaning the code is tightly coupled with use.

The same Controller class without use:

1// MyApp/Controller.php
2namespace MyApp;
3 
4class Controller {
5 public function output() {
6 $service = new MyApp\ComponentA\Service();
7 $service->method();
8 }
9}

No question on which Service class is created and no coupling.

There are other problems with use, such as dynamic naming. But that's another post. use breaks what namespaces solve.

Spend a few extra keystrokes typing absolute namespaces for code clarity and portability. Future developers will thank you.

Find this interesting? Let's continue the conversation on Twitter.