usar spl_autoload_register psr namespace funciona ejemplos composer como __autoload php oop autoload

php - spl_autoload_register - La mejor solución para__autoload



spl_autoload_register ejemplos (11)

Si está utilizando APC, debe habilitar el almacenamiento en caché de código de operación. Creo que esto tendría más beneficios para el rendimiento y sería una solución más transparente que cualquier estrategia de clase / archivo que emplee.

La segunda sugerencia es usar cualquier estrategia de clase / archivo que sea más fácil de desarrollar, pero en su sitio de producción, debe concatenar las clases más frecuentemente en un archivo y asegurarse de que se carguen durante cada solicitud (o en caché con APC).

Haz algunos experimentos de rendimiento con el aumento de conjuntos de tus clases. Probablemente descubrirá que el beneficio de reducir la E / S de archivos es tan importante, que unir todas las clases en un solo archivo es una ganancia neta, incluso si no necesita todas las clases durante cada solicitud.

A medida que nuestra aplicación PHP5 OO creció (tanto en tamaño como en tráfico), decidimos revisar la estrategia __autoload ().

Siempre nombramos el archivo por la definición de clase que contiene, por lo que el Cliente de la clase estaría dentro de Customer.php. Solíamos enumerar los directorios en los que potencialmente existe un archivo, hasta que se encuentra el archivo .php correcto.

Esto es bastante ineficiente, ya que es posible que esté pasando por una serie de directorios que no necesita, y lo hace en cada solicitud (por lo tanto, hacer un montón de llamadas stat ()).

Soluciones que vienen a mi mente ...

-utilice una convención de nomenclatura que dicte el nombre del directorio (similar a PEAR). Desventajas: no escala demasiado, lo que resulta en nombres de clase horribles.

-comenzar con algún tipo de matriz preconstruida de las ubicaciones (propulsor hace esto por su __autoload). Desventaja: requiere una reconstrucción antes de implementar un nuevo código.

-construye la matriz "sobre la marcha" y la almacena en caché. Esta parece ser la mejor solución, ya que permite los nombres de clase y la estructura de directorios que desee, y es totalmente flexible en cuanto a que los nuevos archivos se agregan a la lista. Las preocupaciones son: dónde almacenarlo y qué pasa con los archivos eliminados / movidos. Para el almacenamiento elegimos APC, ya que no tiene la sobrecarga de E / S del disco. Con respecto a las eliminaciones de archivos, no importa, ya que probablemente no las necesites en ninguna parte de todos modos. En cuanto a los movimientos ... eso no se ha resuelto (lo ignoramos porque históricamente no fue muy frecuente para nosotros).

¿Alguna otra solución?


function __autoload( $class ) { $patterns = array( ''%s.class.php'', ''%s.interface.php'' ); foreach( explode( '';'', ini_get( ''include_path'' ) ) as $dir ) { foreach( $patterns as $pattern ) { $file = sprintf( $pattern, $class ); $command = sprintf( ''find -L %s -name "%s" -print'', $dir, $file ); $output = array(); $result = -1; exec( $command, $output, $result ); if ( count( $output ) == 1 ) { require_once( $output[ 0 ] ); return; } } } if ( is_integer( strpos( $class, ''Exception'' ) ) ) { eval( sprintf( ''class %s extends Exception {}'', $class ) ); return; } if ( ! class_exists( $class, false ) ) { // no exceptions in autoload :( die( sprintf( ''Failure to autoload class: "%s"'', $class ) ); // or perhaps: die ( ''<pre>''.var_export( debug_backtrace(), true ).''</pre>'' ); } }

También podría encontrar otra forma menos dependiente de posix para iterar directorios, pero esto es lo que he estado usando.

Atraviesa todos los directorios en el include_path (establecido en php.ini o .htaccess) para encontrar una clase o interfaz.


Viejo hilo, pero pensé que podría exponer mi método aquí de todos modos, tal vez podría ayudar a alguien. Esta es la forma en que defino __autoload() en el punto de entrada de mi sitio /path/to/root/www/index.php por ejemplo:

function __autoload($call) { require(''../php/''.implode(''/'', explode(''___'', $call)).''.php''); }

Todos los archivos PHP están organizados en un árbol

/path/to/root/php /Applications /Website Server.php /Model User.php /Libraries /HTTP Client.php Socket.php

Y el nombre de las clases son:

Applications___Website___Server Model___User Libraries___HTTP___Client Libraries___Socket

Es rápido y si el archivo no está presente, se bloqueará y su registro de errores le dirá qué archivo falta. Puede parecer un poco duro, pero si intenta usar la clase incorrecta, es su problema.

NB: fue para PHP 5 <5.3, entonces para PHP 5.3 puede usar espacios de nombres, la razón por la que utilicé 3 _ como separador es que es un reemplazo fácil de hacer para el uso del espacio de nombres 5.3.


¿Ha investigado el uso de Zend_Loader (con registerAutoload () ) en lugar de solo el nativo __autoload() ? He usado Zend_Loader y he estado contento con él, pero no lo he visto desde una perspectiva de rendimiento. Sin embargo, esta publicación de blog parece haber hecho un análisis de rendimiento en ella; podría comparar esos resultados con las pruebas de rendimiento internas de su autocargador actual para ver si pueden cumplir sus expectativas.


CodeIgniter hace algo similar con la función load_class. Si recuerdo correctamente, es una función estática que contiene una matriz de objetos. La llamada a la función es:

load_class($class_name, $instansiate);

entonces en tu caso

load_class(''Customer'', TRUE);

y esto cargaría una instancia de la clase Cliente en la matriz de objetos.

La función fue bastante directa. Lamento no poder recordar el nombre de la clase en la que estaba. Pero sí recuerdo que hay varias clases que se cargan, como la clase Routing, la clase Benchmark y la clase URI.


También he estado jugando con autocarga durante bastante tiempo, y terminé implementando un tipo de autocargador de espacio de nombres (sí, también funciona para PHP5.2).

La estrategia es bastante simple: primero tengo una clase singleton (cargador) que tiene una llamada que simula la import . Esta llamada toma un parámetro (el nombre de clase completo para cargar) y calcula internamente el nombre del archivo desde el que se debug_backtrace() utilizando debug_backtrace() ). La llamada almacena esta información en una matriz asociativa para usarla más adelante (utilizando el archivo de llamada como clave y una lista de clases importadas para cada clave).

El código típico se ve así:

<?php loader::import(''foo::bar::SomeClass''); loader::import(''foo::bar::OtherClass''); $sc = new SomeClass(); ?>

Cuando se activa la carga automática, el nombre de clase completo que se almacenó en la matriz se transforma en una ubicación real del sistema de archivos (los dos puntos se reemplazan por separadores de directorios) y se incluye el nombre del archivo resultante.

Sé que no es exactamente lo que estaba pidiendo, pero puede resolver el problema del recorrido del directorio, ya que el cargador sabe exactamente dónde está exactamente el archivo (con la característica adicional de que podría organizar sus clases en directorios, sin un rendimiento aparente). pena).

Podría proporcionar algunos ejemplos de trabajo, pero soy demasiado tímido para mostrar mi código malicioso al público. Espero que la explicación anterior sea útil ...


Hay 2 enfoques generales que funcionan bien.
Primero está usando la estructura de nombres de clase estándar de PEAR así que solo necesita reemplazar ''_'' con / para encontrar la clase.

http://pear.php.net/manual/en/pear2cs.rules.php

O puede buscar directorios para las clases php y asignar el nombre de la clase al archivo. Puede guardar el mapa de clase en la memoria caché para guardar los directorios de búsqueda en cada carga de página.
El marco Symfony usa esos enfoques.

En general, es mejor seguir la estructura estándar ya que es más simple y no necesita almacenar nada en la memoria caché, además de que usted está siguiendo las pautas recomendadas.


Usamos algo parecido a la última opción, excepto con una comprobación file_exists () antes de requerir. Si no existe, reconstruya el caché y vuelva a intentarlo. Obtiene la estadística extra por archivo, pero maneja movimientos de forma transparente. Muy útil para un desarrollo rápido donde muevo o cambio el nombre de las cosas con frecuencia.


He usado esta solución en el pasado, publiqué sobre ella como referencia y puede ser interesante para algunos de ustedes ...

Aquí está


Tengo convenciones de nomenclatura específicas para cada ''tipo'' de clase (controladores, modelos, archivos de biblioteca, etc.), así que actualmente hago algo similar a:

function __autoload($class){ if($class matches pattern_1 and file_exists($class.pattern_1)){ //include the file somehow } elseif($class matches pattern_2 and file_exists($class.pattern_2)){ //include the file somehow } elseif(file_exists($class.pattern_3)){ //include the file somehow } else { //throw an error because that class does not exist? } }


function __autoload($class_name) { $class_name = strtolower($class_name); $path = "../includes/{$class_name}.php"; if (file_exists($path)) { require_once($path); } else { die("The file {$class_name}.php could not be found!"); } }