Estándar de Autoloading PSR-4
Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy — lección 12 de 91.
PSR-4 es un estándar que define cómo las clases de PHP deben cargarse automáticamente en función de su espacio de nombres y la ubicación del archivo. En lugar de incluir manualmente cada archivo de clase, PSR-4 permite que PHP encuentre y cargue clases automáticamente cuando las utilizas.
La regla fundamental es simple: el espacio de nombres debe coincidir con la estructura de directorios. Si tienes una clase App\Models\User, el archivo debe estar ubicado en App/Models/User.php.
<?php
// Archivo: src/Models/User.php
namespace App\Models;
class User {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
Puedes escribir una función de carga automática (autoloader) simple que siga las reglas PSR-4:
<?php
// Archivo: autoload.php
spl_autoload_register(function ($class) {
$prefix = 'App\\';
$baseDir = __DIR__ . '/src/';
// Comprobar si la clase utiliza nuestro prefijo de espacio de nombres
if (strpos($class, $prefix) === 0) {
$relativeClass = substr($class, strlen($prefix));
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
if (file_exists($file)) {
require $file;
}
}
});
La función spl_autoload_register le indica a PHP que llame a tu función cada vez que encuentre una clase desconocida. La función convierte el espacio de nombres en una ruta de archivo y lo carga.
Punto clave: PSR-4 crea un mapeo predecible entre espacios de nombres y rutas de archivos. Cuando ves App\Models\User, sabes inmediatamente que el archivo está en src/Models/User.php. Esta convención hace que los proyectos sean más fáciles de navegar y mantener.
Desafío
FácilVamos a construir un sistema de carga automática (autoloading) PSR-4 simple que cargue automáticamente las clases basándose en su espacio de nombres (namespace) y la ubicación del archivo.
Crearás un proyecto con tres archivos que demuestran cómo PSR-4 mapea los espacios de nombres a las rutas de directorio:
src/Services/Logger.php— Define una claseLoggeren el espacio de nombresApp\Services. Debe tener una propiedadpublic $name, un constructor que acepte y establezca el nombre, y un métodolog($message)que devuelva"[name] logged: [message]".src/Services/Mailer.php— Define una claseMaileren el espacio de nombresApp\Services. Debe tener una propiedadpublic $sender, un constructor que acepte y establezca el remitente, y un métodosend($to)que devuelva"Mail from [sender] to [to]".main.php— Crea un autoloader PSR-4 usandospl_autoload_registerque mapee el prefijo de espacio de nombresApp\al directoriosrc/. El autoloader debe convertir los separadores de espacio de nombres en separadores de directorio y añadir.phppara encontrar el archivo correcto. Después de registrar el autoloader, usa la palabra claveusepara importar ambas clases, luego crea unLoggercon el nombre"FileLogger"y unMailercon el remitente"admin@site.com". Imprime el resultado de llamar alog("System started")en el logger ysend("user@example.com")en el mailer (cada uno en su propia línea).
La clave es que tu función de autoloader recibe el nombre completo de la clase (como App\Services\Logger) y debe convertirlo en una ruta de archivo (src/Services/Logger.php). Usa strpos para verificar si la clase comienza con tu prefijo de espacio de nombres, substr para obtener el nombre relativo de la clase, y str_replace para convertir las barras invertidas en barras diagonales.
Hoja de referencia
PSR-4 es un estándar que define cómo las clases de PHP deben cargarse automáticamente basándose en su espacio de nombres (namespace) y la ubicación del archivo. El espacio de nombres debe coincidir con la estructura de directorios.
Ejemplo de estructura de clase:
<?php
// Archivo: src/Models/User.php
namespace App\Models;
class User {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
Autocargador (autoloader) PSR-4 usando spl_autoload_register:
<?php
spl_autoload_register(function ($class) {
$prefix = 'App\\';
$baseDir = __DIR__ . '/src/';
// Comprobar si la clase usa nuestro prefijo de espacio de nombres
if (strpos($class, $prefix) === 0) {
$relativeClass = substr($class, strlen($prefix));
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
if (file_exists($file)) {
require $file;
}
}
});
El autocargador convierte los separadores de espacio de nombres (\) en separadores de directorio (/) y añade .php para encontrar el archivo correcto. Por ejemplo, App\Models\User se mapea a src/Models/User.php.
Pruébalo tú mismo
<?php
// Implementación de Autoloader PSR-4
// TODO: Registrar un autoloader usando spl_autoload_register
// El autoloader debe:
// 1. Verificar si la clase comienza con el prefijo de espacio de nombres 'App\'
// 2. Eliminar el prefijo 'App\' para obtener el nombre relativo de la clase
// 3. Convertir los separadores de espacio de nombres (\) en separadores de directorio (/)
// 4. Anteponer 'src/' y añadir '.php' para construir la ruta del archivo
// 5. Requerir el archivo si existe
spl_autoload_register(function ($class) {
// TODO: Definir el prefijo del espacio de nombres y el directorio base
// TODO: Verificar si la clase usa el prefijo del espacio de nombres (usar strpos)
// TODO: Obtener el nombre relativo de la clase (usar substr)
// TODO: Construir la ruta del archivo reemplazando \ por / (usar str_replace)
// TODO: Requerir el archivo si existe
});
// TODO: Usar la palabra clave 'use' para importar las clases Logger y Mailer
// TODO: Crear una instancia de Logger con el nombre "FileLogger"
// TODO: Crear una instancia de Mailer con el remitente "admin@site.com"
// TODO: Imprimir el resultado de log("System started")
// TODO: Imprimir el resultado de send("user@example.com")
?>Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de OOP
Archivos externosIntroducción a OOPClases vs ObjetosLa palabra clave $thisMétodosPropiedadesConstructor (__construct)Destructor (__destruct)Resumen - Calculadora simple4Herencia
Herencia básicaLa palabra clave parent::Sobrescritura de métodosLa palabra clave finalClases abstractasResumen - Jerarquía de empleados7Encapsulamiento
Público, Protegido, PrivadoModificadores de acceso a fondoGetters y SettersOcultamiento de informaciónPromoción de constructor (8.0)Resumen - Sistema de registros de estudiantes10Conceptos avanzados de POO
Composición vs. HerenciaInyección de dependenciasClases anónimasEnums (PHP 8.1)Fibers (PHP 8.1)Clonación de objetos a fondoGeneradores e Iteradores13Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository2Espacios de nombres y Autoloading
Introducción a los espacios de nombresLa palabra clave useEstándar de Autoloading PSR-4Autoloader de ComposerResumen - Proyecto organizado5Interfaces y Contratos
Introducción a las InterfacesImplementación de InterfacesImplementación de Múltiples InterfacesInterfaz vs Clase AbstractaType Hinting con InterfacesResumen - Calculadora de Formas8Métodos mágicos
Introducción a los métodos mágicos__toString y __debugInfo__get, __set, __isset, __unset__call y __callStatic__clone y clonación de objetos__serialize y __unserializeResumen - Colección personalizada3Propiedades de clase
Propiedades de instancia vs. estáticasConstantes en clasesMétodos y propiedades estáticosPropiedades privadas y protegidasPropiedades de solo lectura (PHP 8.1)Resumen - Gestor de cuenta bancaria6Polimorfismo
Sobrescritura de métodos revisadaPolimorfismo mediante interfacesType Hinting y tipos de uniónEnlace estático tardíoResumen - Procesador de pagos9Traits
Introducción a los TraitsUso de múltiples TraitsResolución de conflictos de TraitsMétodos abstractos en TraitsTraits frente a herencia12Patrones de diseño Parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón Strategy