Si has trabajado con programación orientada a objetos en PHP y eres un poco ordenado/a seguramente crearás un fichero independiente para cada una de las clases. Es la opción más recomendable. Sin embargo ello te obligará a utilizar de forma reiterada la función require_once() o similar para cargar cada una de las clases en los distintos ficheros de tu proyecto, lo cual resulta pesado y aburrido.

Para resolver este problema utilizaremos la carga automática de clases de PHP 5: __autoload() o spl_autoload_register().

La función de carga básica

Leyendo la documentación oficial vemos que lo que hace la función __autoload() es dar una oportunidad para realizar una acción antes de que el compilador de PHP arroje un error al no encontrar una clase o interface instanciada durante la ejecución. El ejemplo más claro lo podemos ver en este ejemplo tomado de la documentación oficial.

<?php
function __autoload($nombre_clase) {
  require_once("classes/" . $nombre_clase . '.php');
}
$obj  = new MiClase1();
$obj2 = new MiClase2();

Como vemos la función lo que hace cuando no encuentra la clase que instanciamos unas líneas más abajo es buscar los ficheros classes/MiClase1.php y classes/MiClase2.php. En caso de no encontrarlos nos arrojará un Fatal Error dado que utilizamos la función require_once().

Inconvenientes de __autoload()

Sin embargo, y como leerás en la documentación oficial de PHP está desaconsejado su uso. Esto es debido a que cada clase que se carga pasa por esta función y en algún desarrollo grande puede arrojar fallos debido a que se ha podido definir en alguna otra parte del proyecto y puede que busque los ficheros en directorios erróneos y falle la ejecución del código.

Os recomiendo que la leáis pues aporta bastantes ejemplos en el uso de __autoload(), incluyendo el manejo de excepciones.

La función spl_autoload_register()

Para evitar que todas las clases pasen por __autoload() existe la opción de utilizar la función spl_autoload_register() que nos permite registrar distintas funciones de autoload o carga automática de clases, añadiéndolas a la cola de __autoload().

Esto puede ser especialmente útil si aprovechamos otra funcionalidad de programación orientada a objetos: los namespaces. Si no los conoces te vendrá bien la documentación oficial sobre namespaces en PHP 5.

Cuando recuperamos la variable $nombre_clase observaremos que si hemos utilizamos namespaces el nombre de todas las clases viene precedido de su correspondiente namespace.

Tomemos como ejemplo una clase creada con el siguiente código:

<?php
namespace OG;
class Ejemplo {
  public function __construct () {
  }
}

Cuando llega a nuestra función de carga automática lo hace con el nombre OG\Ejemplo. Esto no sólo nos permite aislar la ejecución de código en distintos namespaces, sino aprovecharnos de ello para poder especificar distintos directorios de lectura del fichero de la clase en función del namespace.

Cuando necesito la carga de clases específicas en cualquier proyecto utilizo este sistema para la carga de clases. De este modo me permite tener mi código convenientemente ordenado en clases y su ejecución aislada del resto de proyecto.

La mayoría de frameworks como Laravel, Zend, etc ya tienen implementado este sistema. Sin embargo otros entornos como WordPress carecen de él, así que todo se ejecuta en el mismo espacio de nombres. Una práctica nada recomendable.

Veamos un ejemplo de cómo podríamos implementar este código:

// Classes autoload OG
spl_autoload_register('OG_autoload');
function OG_autoload($classname) {
  $namespace = explode("\\" , $classname)[0];
  if ($namespace == 'OG') {
    $classname = str_replace ('\\', '/', $classname);
    $filename = "classes/". $classname .".class.php";
    require_once( __DIR__ . '/' .  $filename);
  }
}

En mi caso todas las librerías y clases que implemento en mis desarrollos las incluyo en el namespace OG. Si en el nombre de la clase a cargar detecto que se encuentra en dicho namespace procedo a ejecutar el resto del código. Para ello simplemente busco cada una de las clases dentro de su correspondiente directorio.

Si utilizaramos distintas jerarquías dentro de los espacios de nombre como OG\Subnivel1\Subnivel2 simplemente deberemos de respetar los niveles de anidación creando nuevos subdirectorios en donde almacenar los ficheros con las correspondientes clases.

Si habéis programado con algún framework como Symfony, Zend o Laravel este es el sistema de carga de clases que utilizan y no os resultará desconocido.

Conclusión

A la hora de programar lo ideal es automatizar al máximo nuestro trabajo evitándonos tareas tediosas como la carga y búsqueda de clases y/o ficheros. Para ello PHP 5 nos ofrece funciones muy sencillas dentro de la Standard PHP Library que facilitan esta tarea. Además unido a la ejecución de código en namespaces aún hace nuestro código más sencillo de entender, ordenado y reutilizable.

Si trabajas en algunos entornos como WordPress en el que interactuan miles de plugins y funciones diferentes corres el riesgo de declarar nombres de clases que quizás alguien ya haya utilizado. Para ello es fundamental el uso de namespaces para declarar espacios de ejecución separados.

Este es sólo un sencillo ejemplo, que por supuesto se podría mejorar. Encantado de recibir sugerencias y mejoras.

Fuentes

Comparte si te ha gustado

Autor:
Última actualización:

3 comentarios

  1. Mola el artículo 🙂
    Es interesante que la gente sepa cómo definir un autoloader para cuando se trabaja en proyectos con CMSs como WordPress, para poder cargar las clases de tu plugin.
    No obstante se echa en falta alguna mención a los estándares de autoloading y al autoloader de composer.
    http://www.php-fig.org/psr/psr-4/
    https://getcomposer.org/doc/01-basic-usage.md#autoloading

    Casi todos los frameworks están dejando de definir sus propios complementos de autoloading en beneficio de composer, que ha demostrado ser de los más eficientes y fáciles de configurar.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

De acuerdo con lo dispuesto en el Reglamento (UE) 2016/679 de 27 de abril de 2016, consiento que mis datos sean tratados bajo la responsabilidad de Oscar Gascón Arjol para recibir respuesta a consultas. publicación de comentarios del blog y que las conserve mientras haya un interés mutuo para ello. Me doy por informado que tengo derecho a revocar este consentimiento en cualquier momento y a ejercer los de acceso, rectificación, portabilidad y supresión de mis datos y los de limitación y oposición al tratamiento dirigiéndome por email a me@oscargascon.es. También estoy informado de que puedo reclamar ante la autoridad de control a www.agpd.es.