Cómo usar autoload en varios componentes simultáneamente 1
Autoload es uno de los llamados métodos mágicos de PHP que se dispara “mágicamente” cuando, al instanciar una clase, el interprete no es capaz de localizarla porque no se ha hecho el include/require del archivo correspondiente. Con autoload podemos sobrecargar esta funcionalidad y especificarle a PHP donde debe buscar sin tener que indicar explicita mente todos los archivos de clases de nuestro proyecto mediante include/require.
El problema viene cuando nuestro proyecto utiliza su propio autoload y un componente de un tercero utiliza otro autoload completamente diferente: sólo puede haber un punto para interceptar la llamada “autoload” e inevitablemente colisionan.
Afortunadamente la SPL proporciona un mecanismo para apilar métodos autoload, tantos como sean necesarios, y evitar las colisiones. Veamos un ejemplo:
-
class Component1
-
{
-
public function __construct( $foo )
-
{
-
echo $foo;
-
}
-
}
-
-
function __autoload ( $class_name )
-
{
-
if ( !exist_class($class_name) )
-
{
-
{
-
require ($f);
-
}
-
else
-
{
-
throw new Exception(‘Unnable to find class ‘ . $class_name . ‘!’, 0);
-
}
-
}
-
}
-
class Component2
-
{
-
public function __construct( $bar )
-
{
-
echo $bar;
-
}
-
}
-
-
function __autoload ( $class_name )
-
{
-
if ( !exist_class($class_name) )
-
{
-
{
-
require ($f);
-
}
-
else
-
{
-
throw new Exception(‘Unnable to find class ‘ . $class_name . ‘!’, 0);
-
}
-
}
-
}
Las clases Component1 y Component2 tienen dos funciones __autoload() diferentes.
-
include ‘./Component1.php’;
-
include ‘./Component2.php’;
-
-
$c1 = new Component1_Lib(); // error!!
Los dos callbacks autoload colisionan.
Utizando SPL podemos detectar si ya hay un callback autoload definido para sobreescribirlo, o apilar el nuestro. Además la función autoload puede meterse como metodo de una clase y mejorar un poco el aspecto del codigo:
-
-
class Component1
-
{
-
public function __construct( $foo )
-
{
-
echo $foo;
-
}
-
-
public function autoload( $class_name )
-
{
-
if ( !exist_class($class_name) )
-
{
-
{
-
require ($f);
-
}
-
else
-
{
-
throw new Exception(‘Unnable to find class ‘ . $class_name . ‘!’, 0);
-
}
-
}
-
}
-
}
-
-
-
$callbacks = spl_autoload_functions();
-
// no autoload callbacks in stack
-
if ( $callbacks === false )
-
{
-
}
-
else
-
{
-
// unregister existing callbacks
-
foreach ( $callbacks as $callback )
-
{
-
spl_autoload_unregister($callback);
-
}
-
-
// register custom callback
-
-
// re-register old ones
-
foreach ( $callbacks as $callback )
-
{
-
spl_autoload_register($callback);
-
}
-
}
-
Cuidado porque la función autoload no es demasiado liviana y un uso abusivo puede provocar una bajada de rendimiento en el programa, pero de momento y hasta la versión 5.3, sin espacios de nombres en PHP no podemos hacer gran cosa ![]()
















menéame