Autoloaders en PHP – dos corriendo a la vez

Entiendo cómo registrar autocargadores e incluso cómo crear uno, eso no es problema. Sin embargo, el problema principal es cómo tiene dos cargadores automáticos funcionando uno al lado del otro para algo como:

class project_one_folder_class extends project_two_folder_class{} 

Notarás que la clase hija pertenece a un proyecto que se está acercando y llamando a la clase principal que se ubica en un proyecto diferente.

La forma en que se vinculan los proyectos Las clases del proyecto dos siempre se ven en el autocargador, sin importar si las clases del proyecto uno nunca se ven.

Así que la forma en que pensé alrededor de esto fue escribir dos cargadores automáticos y registrarlos porque php mirará y luego el otro. ¿Cómo php parece estar buscando en una y no en la otra?

¿Como resolverias esto?

Editar

El proyecto dos es padre, el proyecto uno es hijo. Esta es una pregunta más amplia que lo que se publicó en esta pregunta .

Para expandir mejor esta es mi clase.

 class AisisCore_Loader_AutoLoader{ protected static $_instance; public function get_instance(){ if(null == self::$_instance){ self::$_instance = new self(); } return self::$_instance; } public function reset_instance(){ self::$_instance = null; } public function register_auto_loader(){ spl_autoload_register(array($this, 'load_class')); spl_autoload_register(array($this, 'load_child_class')); } public function load_class($class){ $path = str_replace('_', '/', $class); if(file_exists(get_template_directory() . '/' . $path . '.php')){ require_once(get_template_directory() . '/' . $path . '.php'); } } public function load_child_class($class){ $path = str_replace('_', '/', $class); if(file_exists(get_stylesheet_directory() . '/' . $path . '.php')){ require_once(get_stylesheet_directory() . '/' . $path . '.php'); } } } 

Actualmente esta clase cargará cualquier cosa en el proyecto principal. Incluso cargará objetos del proyecto principal en el proyecto secundario. Sin embargo, ningún objeto hijo puede cargarse utilizando esta clase, ya que no se encuentra.

Quienes estén familiarizados con WordPress dirán instantáneamente, sí, porque tienen get_template_directory cuando quieran get_stylesheet_directory Como sea, sabiendo esto, quiero escribir dos cargadores automáticos, uno que cargará objetos de proyectos secundarios usando get_stylesheet_directory y luego uno que cargará los objetos principales. a través de get_stylesheet_directory para que:

class project_one_folder_class extends project_two_folder_class{}

trabajos y cargas, sin error.

Esto es un poco difícil, pero en realidad solo necesita un autocargador que simplemente verifique dentro de múltiples directorios:

 abstract class Hakre_Theme_AutoLoader { public static $directories; public static function init() { // configure paths self::$directories = array( get_template_directory(), // current theme, parent in case of childtheme get_stylesheet_directory(), // current theme, child in case of childtheme ); // please double check if you really need to prepend return spl_autoload_register('Hakre_Theme_AutoLoader::autoload', true, true); } public static function autoload($class) { $filename = str_replace('_', '/', $class) . '.php'; foreach (self::$directories as $directory) { $path = $directory . '/' . $filename; if (is_file($path)) { require($path); return; # leave because the class has been loaded } } } } Hakre_Theme_AutoLoader::init(); ## If you're unsure all worked out properly: var_dump(Hakre_Theme_AutoLoader::$directories); 

Esto realmente debería hacerlo, sin embargo no lo he probado. Vea var_dump , puede depurar si los directorios correctos están registrados o no. No es necesario tener varias devoluciones de llamada solo porque desea verificar en dos directorios.

Bueno, por supuesto, podrías buscar una segunda ruta cuando el primer archivo_exista devuelva falso, en el mismo autocargador.

También puede registrar un segundo autocargador para la segunda ruta.

Los documentos PHP abordan esto:

Si debe haber varias funciones de autocarga, spl_autoload_register() permite. Crea efectivamente una cola de funciones de autocarga, y las ejecuta a través de cada una de ellas en el orden en que están definidas. Por el contrario, __autoload() solo se puede definir una vez.

Separar el proceso de carga automática!

PHP funciona así: en algún punto, la ejecución del código tropieza con una referencia de clase que aún no está cargada. $obj = new project_one_folder_class()

Ahora se invocan las funciones de autocargador registradas, comenzando por la que se agregó primero (a menos que las que se agregaron posteriormente utilicen el parámetro “anteponer”).

La primera (y todas las siguientes) funciones de autocarga obtienen el nombre de la clase que debe cargarse. La función ahora tiene la tarea de decidir

  1. ¿Es su tarea cargar esta clase? Si no, no haga nada, deje que las otras funciones intenten cargarlo.
  2. Si esta función es responsable de cargar la clase, intente crear una ruta de acceso y un nombre de archivo a partir del nombre de la clase conocida, y solicite este archivo.

El paso 1 generalmente se resuelve al observar si el nombre de clase que se va a cargar comienza con un cierto prefijo. En su caso, el autocargador responsable de cargar las clases comenzando con “project_one_” NO debería intentar cargar ninguna otra clase comenzando con otra cosa.

El paso 2 tiene lugar si el autocargador sabe que debe realizar la carga automática. Ahora transforma el nombre de la clase en una ruta de acceso y un nombre de archivo relativos, agrega el directorio base y luego requiere el archivo.

Requerir un archivo que defina una clase que amplíe otra clase (o implemente interfaces) puede desencadenar otra ejecución de carga automática con clases aún desconocidas. En su caso, el proceso de autocarga se inicia nuevamente con el nombre de clase “project_two_folder_class”. Tenga en cuenta que el primer autocargador para las clases “project_one_” se llamará nuevamente con este nombre de segunda clase, pero no debe hacer nada, porque no sabe cómo cargar estas clases. Esto corresponde al autocargador que conoce las clases “project_two_”.

El orden de registro no debe importar para los diferentes cargadores automáticos. Si lo hace, los cargadores automáticos se portan mal.

Debido a que es un patrón común simplemente transformar cualquier carácter de subrayado en los nombres de clase en DIRECTORY_SEPARATOR, así como las barras diagonales inversas desde espacios de nombres, agregue “.php” al final, y luego intente cargar este archivo desde un directorio base definido, el código para dos de estos cargadores automáticos serán idénticos, y el problema se reduce a la configuración de una sola función de autocarga con estos dos casos: ¿Qué prefijo debe estar presente y en qué directorio base debe esperar el archivo, siempre que el nombre de la clase pueda transformarse en una ruta relativa al archivo.

Comprobar en cada caso si el archivo existe en un determinado directorio o no es óptimo para el rendimiento. Terminará haciendo muchos controles de archivos que podrá saber que no puede cargar simplemente mirando el nombre de la clase.

Y por cierto: las funciones del autocargador no necesitan ser simples. De hecho, su implementación singleton está rota e inútil. Cree una instancia del autocargador con algo new , tal vez pase algunos valores de configuración al constructor, y llame a spl_autoload_register() , y debe haber terminado.

Puede agregar más de un cargador, simplemente registre cada función con spl_autoload_register ().

estilo de procedimiento:

 spl_autoload_register('loader_function1')); // your second class location spl_autoload_register('loader_function2')); 

o en un estilo OO

 spl_autoload_register(array($this, 'loader_function1')); spl_autoload_register(array($this, 'loader_function2')); 

Sin embargo, en función de su pregunta: probablemente pueda lograr lo mismo al tener un autocargador más flexible, vea mi respuesta en una pregunta diferente aquí: Autocargador de clase en el complemento de WordPress