Curso de PHP

Namespace en PHP: organizar el código y evitar conflictos

Por Víctor Peña · Publicado el

Namespace en PHP

Hola, ¿cómo están? Continuando con el curso de PHP, hoy veremos los namespaces: la forma de organizar el código de un proyecto y evitar que dos clases con el mismo nombre choquen entre sí.

¡Empecemos!

El problema que resuelven

Imagina que tu proyecto tiene una clase Usuario, y además instalas una librería que también trae una clase Usuario. En PHP no puede haber dos clases con el mismo nombre: el programa falla.

Antes de los namespaces, la solución era poner prefijos larguísimos: MiEmpresa_Modelos_Usuario. Funcionaba, pero era feo y frágil.

Un namespace es como una carpeta para tus clases. Igual que puedes tener dos archivos llamados informe.pdf en carpetas distintas, puedes tener dos clases Usuario en namespaces distintos.

Declarar un namespace

Se declara con namespace, y debe ser la primera instrucción del archivo:

<?php

namespace App\Modelos;

class Usuario
{
    public function __construct(
        public string $nombre,
    ) {}
}

El nombre completo de esa clase ahora es App\Modelos\Usuario.

La barra invertida \ separa los niveles, igual que la barra separa carpetas en una ruta.

Usar una clase de otro namespace

Desde otro archivo, tienes tres formas.

1. Nombre completo:

<?php
$usuario = new \App\Modelos\Usuario("Víctor");

2. Importar con use, que es lo habitual:

<?php

namespace App\Controladores;

use App\Modelos\Usuario;

class UsuarioControlador
{
    public function crear(): Usuario
    {
        return new Usuario("Víctor");
    }
}

3. Importar el namespace y usar la parte final:

<?php
use App\Modelos;

$usuario = new Modelos\Usuario("Víctor");

La segunda es la que verás en el 95 % del código real.

Alias: resolver los nombres repetidos

Cuando necesitas dos clases con el mismo nombre, le pones alias a una:

<?php

use App\Modelos\Usuario;
use Vendor\Libreria\Usuario as UsuarioExterno;

$mio = new Usuario("Víctor");
$otro = new UsuarioExterno();

Aquí se ve el valor de los namespaces: las dos clases conviven sin problema.

La barra invertida al inicio

Este detalle confunde mucho al principio.

Dentro de un namespace, PHP busca las clases en ese mismo namespace por defecto. Si quieres una clase global —las que trae PHP—, tienes que anteponer \:

<?php

namespace App\Servicios;

class Reporte
{
    public function generar(): void
    {
        $fecha = new \DateTime();          // clase global de PHP
        // new DateTime();                 // buscaría App\Servicios\DateTime
    }
}

Lo mismo con excepciones e interfaces nativas: \Exception, \InvalidArgumentException, \Countable.

La alternativa, más legible, es importarlas arriba:

<?php

namespace App\Servicios;

use DateTime;
use InvalidArgumentException;

class Reporte
{
    public function generar(): void
    {
        $fecha = new DateTime();
    }
}

Con las funciones no pasa lo mismo: si PHP no encuentra la función en el namespace actual, la busca en el global. Por eso count() o array_map() funcionan sin barra.

Cómo se organiza un proyecto

La convención es que el namespace refleje la estructura de carpetas:

src/
├── Modelos/
│   ├── Usuario.php        → App\Modelos\Usuario
│   └── Producto.php       → App\Modelos\Producto
├── Servicios/
│   ├── Facturacion.php    → App\Servicios\Facturacion
│   └── Notificador.php    → App\Servicios\Notificador
└── Controladores/
    └── PedidoControlador.php → App\Controladores\PedidoControlador

Esa correspondencia no es solo estética: es lo que permite que el autoload funcione.

La conexión con Composer y PSR-4

Aquí encaja lo que vimos en la lección de Composer.

En tu composer.json:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

Eso le dice a Composer: «todo lo que empiece por App\ está en la carpeta src/».

Con esa configuración, escribir new App\Modelos\Usuario() hace que Composer busque solo el archivo src/Modelos/Usuario.php y lo cargue. No necesitas escribir ni un require.

Después de modificar el composer.json, regenera el autoload:

composer dump-autoload

Si alguna vez PHP no encuentra una clase que sí existe, ese comando resuelve la mayoría de los casos.

Sub-namespaces

Puedes anidar tanto como necesites:

<?php

namespace App\Modelos\Facturacion;

class NotaCredito { }

La recomendación práctica: no pases de tres o cuatro niveles. Más allá, los nombres se vuelven interminables y no aporta claridad.

Importar funciones y constantes

Menos conocido, pero útil:

<?php

use function App\Ayudantes\formatearMoneda;
use const App\Config\IVA;

echo formatearMoneda(1500);
echo IVA;

Un ejemplo completo

<?php
// src/Contratos/Notificador.php

namespace App\Contratos;

interface Notificador
{
    public function enviar(string $mensaje): bool;
}
<?php
// src/Servicios/NotificadorEmail.php

namespace App\Servicios;

use App\Contratos\Notificador;

class NotificadorEmail implements Notificador
{
    public function enviar(string $mensaje): bool
    {
        echo "Enviando: $mensaje\n";
        return true;
    }
}
<?php
// index.php

require 'vendor/autoload.php';

use App\Servicios\NotificadorEmail;

$notificador = new NotificadorEmail();
$notificador->enviar("Pedido confirmado");

Un solo require, el del autoload de Composer. Todo lo demás se carga solo.

Errores comunes

  • Poner el namespace después de otro código. Debe ser la primera instrucción, salvo declare(strict_types=1).
  • Olvidar la \ al usar clases nativas de PHP dentro de un namespace.
  • Que el namespace no coincida con la carpeta. El autoload no encuentra el archivo.
  • Olvidar composer dump-autoload después de mover o renombrar archivos.
  • Usar barra normal / en lugar de la invertida \.

Para cerrar

Los namespaces organizan el código y evitan choques de nombres, pero su verdadero valor aparece combinados con el autoload de Composer: escribes use, y la clase aparece.

La regla de oro: que el namespace refleje siempre la estructura de carpetas. Con eso, todo lo demás funciona solo.

En la siguiente lección veremos los traits.

Saludos y éxitos.

Norvic Software

Desarrollamos el software que tu empresa necesita

Somos una fábrica de software en Bolivia. Construimos sistemas a medida y aplicaciones móviles, y llevamos Inteligencia Artificial a las empresas que ya tienen un sistema funcionando.

Solicitar cotizaciónVer todos los servicios

Cotización sin costo · Respuesta directa por WhatsApp