Jason McCreary

a PHP and iOS developer. a thinker.

PHP Namespaces: Avoid use

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:

MyApp/Service.php
1
2
3
4
5
6
7
namespace MyApp;

class Service {
  public function method() {
      echo __NAMESPACE__ . '\Service';
  }
}
MyApp/ComponentA/Service.php
1
2
3
4
5
6
7
namespace MyApp\ComponentA;

class Service {
  public function method() {
      echo __NAMESPACE__ . '\Service';
  }
}

A Controller class with use:

MyApp/Controller.php
1
2
3
4
5
6
7
8
9
10
namespace MyApp;

use MyApp\ComponentA\Service;

class Controller {
  public function output() {
      $service = new Service();
      $service->method();
  }
}

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

It may be straightfoward with the entire codebase in front of you. 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:

MyApp/Controller.php
1
2
3
4
5
6
7
8
namespace MyApp;

class Controller {
  public function output() {
      $service = new MyApp\ComponentA\Service();
      $service->method();
  }
}

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

There are other problems with use, such as dynamic naming. But you don’t need more convincing. use breaks what namespaces solve.

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

Comments