PHP Namespaces

This is a bonus page that pairs naturally with OOP. As soon as a project combines code from several places — your own classes plus one or more third-party libraries — two authors will eventually pick the same class name. Namespaces solve that by giving classes an address, the same way folders let two files share a name as long as they live in different directories.

1) Why Namespaces Exist

Without namespaces, PHP keeps every class name in one single global list. If your code defines a class Logger and a library you installed also defines a class Logger, PHP cannot tell them apart — loading both causes a fatal “Cannot declare class Logger, because the name is already in use” error.

2) Declaring a Namespace

A namespace is declared with the namespace keyword as the very first statement in a file (aside from an optional declare()).

<?php
  namespace App\Models;

  class User {
    public string $name = '';
  }
?>

The class above is really called App\Models\User, not just User. Another file can freely declare a completely different Payments\User or Legacy\User without any conflict.

3) Importing with use

Typing the full namespaced name everywhere gets verbose, so use imports a class into the current file under a short alias (its own class name, by default).

<?php
  namespace App\Controllers;

  use App\Models\User;

  $u = new User(); // resolves to App\Models\User
?>

4) Fully-Qualified Names

A name starting with a backslash, like \App\Models\User, is fully qualified — it always points to that exact class no matter what namespace the current file is in. This is handy for one-off references without adding a use line.

<?php
  $u = new \App\Models\User();
?>

5) Live Demo: Two Same-Named Classes, Zero Conflict

A single PHP file normally can’t mix namespaced and non-namespaced code freely, but PHP does support a bracketed namespace syntax that lets several namespaces (and the global namespace) coexist in one file. This page uses exactly that at the very top of the file, before <!DOCTYPE html>, to define two classes that are both called Animal:

<?php
  namespace Zoo {
    class Animal {
      public function type(): string { return 'Zoo Animal'; }
    }
  }

  namespace Farm {
    class Animal {
      public function type(): string { return 'Farm Animal'; }
    }
  }

  namespace {
    $z = new \Zoo\Animal();
    $f = new \Farm\Animal();
    echo $z->type();
    echo $f->type();
  }
?>

The two lines below are the real, live output of $zooAnimal->type() and $farmAnimal->type() — two genuinely separate classes, both named Animal, running side by side on this page without a single naming conflict:

Fully-Qualified ClassLive Result of ->type()
\Zoo\Animal Zoo Animal
\Farm\Animal Farm Animal
Takeaway: in ordinary multi-file projects you would simply put Zoo\Animal and Farm\Animal in their own separate files with a plain namespace Zoo; / namespace Farm; declaration at the top — the bracketed syntax above exists mainly so this one demo file could prove the collision-avoidance live, in a single page.

6) Autoloading with Composer (Conceptual Note)

In real-world projects, you don’t manually require every class file. Composer’s PSR-4 autoloading maps a namespace prefix to a folder, so a class is loaded automatically the first time it is used, based purely on its namespace matching a directory path. For example, a composer.json mapping "App\\": "src/" means the class App\Models\User is expected to live at src/Models/User.php — no manual include needed. This is a conceptual note only; this tutorial site does not set up or demonstrate an actual Composer autoloader.

Honest note about this site: Codingwithsonu.com itself does not use namespaces anywhere — its PHP files (like connection.php, track-visitor.php, and the tutorial pages) use plain global functions and include/require statements. The site is small and predates needing namespaces; they earn their keep once a project has enough files, or enough third-party libraries, that name collisions become a real risk.

7) Best Practices & Common Mistakes

IssueProblemFix
No namespace at all in a growing codebaseClass name collisions as the project or its dependencies growAdopt a namespace per logical module (e.g. App\Models, App\Controllers)
Forgetting the leading backslashnew Animal() inside a namespace resolves to that namespace’s class, not the global oneUse \Animal to explicitly target the global namespace
Mixing folder structure and namespace structureAutoloaders like PSR-4 can’t find the class fileKeep namespace segments and folder names in sync