Saltar al contenido principal

Autoloading

En PHP, cuando trabajamos con programación orientada a objetos, solemos tener muchas clases distribuidas en distintos archivos. Normalmente, para poder usar una clase, debemos incluir manualmente su archivo con require o include:

require_once "clases/Usuario.php";
require_once "clases/Producto.php";

$usuario = new Usuario();
$producto = new Producto();

Este método funciona, pero no escala bien: si el proyecto crece, podemos acabar con decenas o cientos de require.

Para evitar esto, PHP ofrece una funcionalidad llamada autoloading, que permite cargar automáticamente las clases cuando se usan, sin necesidad de incluir sus archivos manualmente.

El nombre de autoload procede de un un método mágico llamado __autoload() que se utilizaba hasta la versión de PHP 7.2, versión donde el método se ha marcado como deprecated.

Algunos beneficios de su uso son:

  • Menos código repetido, ya no necesitamos require por cada clase.
  • Código más limpio y escalable, ideal para proyectos grandes.
  • Estructura clara: las clases se organizan por carpetas de forma lógica.
  • Compatible con frameworks y PSR-4. El autoload es la base de sistemas de carga automática modernos (como los de Composer).

Funcionamiento

Cuando intentas instanciar una clase que aún no ha sido incluida, PHP busca si existe una función o método de autoload registrada. Si la encuentra, la ejecuta automáticamente para cargar la clase desde el archivo correcto.

La función más moderna y recomendada para usar autoload es:

spl_autoload_register(callable $autoload_function);

Con ella registramos una función (anónima o no) que se ejecutará cada vez que PHP necesite cargar una clase.

Ejemplo

Supongamos que tenemos esta estructura de carpetas:

app/
├── Usuario.php
├── Producto.php
index.php

Y cada clase tiene su nombre igual que el archivo:

app/Usuario.php
<?php
class Usuario {
public function saludar() {
echo "Hola desde Usuario";
}
}
app/Producto.php
<?php
class Producto {
public function mostrar() {
echo "Mostrando producto";
}
}

Podemos usar el autoload en index.php así:

<?php
spl_autoload_register(function($nombreClase) {
$ruta = __DIR__ . DIRECTORY_SEPARATOR . "app" . DIRECTORY_SEPARATOR . $nombreClase . ".php";

// Comprobamos si el fichero existe
if (file_exists($ruta)) {
require_once $ruta;
} else {
error_log("No se pudo cargar la clase: $nombreClase ($ruta)");
}
});

$usuario = new Usuario();
$usuario->saludar();

$producto = new Producto();
$producto->mostrar();

Donde:

  • __DIR__ → constante mágica que devuelve la ruta absoluta del directorio donde está autoload.php. Ejemplo: /var/www/html o C:\xampp\htdocs.
  • DIRECTORY_SEPARATOR → Garantiza que la ruta funcione igual en cualquier sistema operativo. Contiene / en Linux/macOS y \ en Windows.
  • "app" → directorio donde están las clases.
  • $nombreClase . ".php" → el nombre del archivo se construye a partir del nombre de la clase.
  • file_exists($ruta) → comprueba si el archivo existe antes de intentar incluirlo.
  • require_once $ruta → incluye el archivo solo una vez (evita inclusiones duplicadas).
  • error_log(...) → si el archivo no se encuentra, registra un mensaje en el log de errores de PHP en lugar de romper la ejecución

Proceso de autoload:

  1. PHP intenta crear un objeto Usuario.
  2. No encuentra la clase cargada, así que llama al autoload.
  3. Nuestra función busca app/Usuario.php.
  4. Si el archivo existe, se incluye automáticamente.
  5. PHP continúa y crea el objeto sin errores.

Ejemplo con namespaces

Si usas namespaces (algo habitual en proyectos medianos y grandes), el autoload también puede adaptarse:

Supongamos la siguiente estructura:

app/
├── Models/
│ ├── Usuario.php
└── Controllers/
├── UsuarioController.php
index.php
app/Models/Usuario.php
<?php
namespace App\Models;

class Usuario {
public function saludar() {
echo "Hola desde App-Models-Usuario";
}
}
app/Controllers/UsuarioController.php
<?php
namespace App\Controllers;

class Usuario {
public function gestionar() {
echo "Hola desde App-Controladores-Usuario";
}
}

Autoload en index.php:

index.php
<?php
spl_autoload_register(function($nombreClase) {
// Convertimos el namespace en ruta
$nombreClase = str_replace('\\', DIRECTORY_SEPARATOR, $nombreClase);

// Ruta completa del fichero
$ruta = __DIR__ . DIRECTORY_SEPARATOR . $nombreClase . '.php';

// Comprobamos si el fichero existe
if (file_exists($ruta)) {
require_once $ruta;
} else {
error_log("No se pudo cargar la clase: $nombreClase ($ruta)");
}
});

use App\Models\Usuario;

$usuario = new Usuario();
$usuario->saludar();

En este caso, App\Models\Usuario se convierte en la ruta App/Models/Usuario.php.