working spl_autoload_register que psr not example php spl-autoload-register

que - ¿Cómo usar spl_autoload_register para varias diectorías en PHP?



spl_autoload_register not working (2)

Con el fin de evitar que las personas que puedan encontrar esta respuesta obtengan información desactualizada, la he actualizado con respecto a los últimos estándares de carga automática de PSR. La respuesta original se ha mantenido con fines históricos y para aquellos que solo están interesados ​​en el autocargador PSR-0.

Respuesta actualizada

PHP-FIG oficialmente ha desaprobado el estándar PSR-0 a favor del autocargador alternativo, PSR-4 . Aunque los dos son similares en algunos aspectos, también son muy diferentes en otros. (Por ejemplo: el manejo de guiones bajos en los nombres de clase).

Puede estar pensando: "Utilizo el PSR-0 ahora y funciona bien". La verdad del asunto es que el PSR-0 todavía funcionará bien para ciertos proyectos. Esto es especialmente cierto cuando se trata de compatibilidad hacia atrás con un paquete que no usa espacios de nombres. El PSR-0 sigue siendo un principio de carga automática decente, pero tiene sus propias deficiencias .

Por supuesto, si hay algo que es una constante con la programación, es que el código eventualmente cambia y las técnicas de programación continúan evolucionando. Puedes hacerte un favor hoy preparándote para el mañana. Por lo tanto, si recién está iniciando un proyecto o está tratando de trasladar un proyecto a una versión más reciente de PHP que puede usar espacios de nombres, debería considerar seriamente usar el autocargador PSR-4.

También vale la pena señalar que si está desarrollando un proyecto que no utiliza espacios de nombres, el PSR-4 no se aplica a usted. En este caso, se aplica el PSR-0 o su propio autocargador personalizado.

Respuesta original

Si desea ir con espacios de nombres en sus clases, entonces la ruta github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md es una buena manera de autocargar. Básicamente, su espacio de nombres representa su estructura de directorios y las clases se pueden cargar según una convención.

Si el método PSR-0 no satisface todas sus necesidades (o no funciona bien con el código existente), aún puede agregar más funciones con spl_autoload_register y PHP las revisará una por una en un intento de cargar clases.

Ejemplo de uso:

Lo primero es lo primero: si no está familiarizado con los espacios de nombres en PHP , se beneficiará de consultar el manual de PHP sobre el tema. Pueden ser un poco confusos al principio, pero sus beneficios valen la confusión inicial.

Así que dije que el PSR-0 funciona al asociar sus espacios de nombres con su estructura de directorios. Vamos a usar sus directorios para un ejemplo. Tienes en tu carpeta raíz (donde sea) lo siguiente:

Project directory: <- Let''s call this directory "MyProject" Controllers: Main.php File.php About.php Libs: Main.php Front_controller.php Models: Index.php File.php Login.php index.php <- Let''s say this is your entry point file, this is where you will be autoloading stuff from.

Ahora echemos un vistazo a su controlador Main.php . Dos cosas a tener en cuenta es que el nombre de la clase debe ser el nombre del archivo y el espacio de nombres para esa clase es la ruta del directorio a ese archivo. Así que Main.php debería verse algo como esto:

<?php namespace MyProject/Controllers; class Main { //Field vars, contructor, methods, etc. all go here. } ?>

Usted haría lo mismo para su modelo de Login

<?php namespace MyProject/Models; class Login { //Field vars, contructor, methods, etc. all go here. } ?>

Ahora, en su archivo index.php (en el directorio raíz - MyProject ) haría su llamada al spl_autoload_register y le daría el autocargador PSR-0.

spl_autoload_register( function ($className) { $className = ltrim($className, ''//'); $fileName = ''''; $namespace = ''''; if ($lastNsPos = strrpos($className, ''//')) { $namespace = substr($className, 0, $lastNsPos); $className = substr($className, $lastNsPos + 1); $fileName = str_replace(''//', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR; } $fileName .= str_replace(''_'', DIRECTORY_SEPARATOR, $className) . ''.php''; require $fileName; }); //Now you can make your call to your objects without a bunch of include/require statements $main = new /MyProject/Controllers/Main(); //Instantiates your ''Main'' controller $login = new /MyProject/Models/Login(); //Instantiates your ''Login'' model

Esperemos que esto ayude a darle un mejor sentido a esto, y nuevamente, si no quiere usar espacios de nombres, siempre puede seguir agregando cierres a la pila de carga automática de SPL. Si lo desea, puede tener 10 cargadores automáticos diferentes y PHP los revisará uno por uno (en el orden en que los definió) utilizando cada función para intentar cargar una clase. Sin embargo, un par de autocargadores basados ​​en convenciones es un poco más limpio y más de un método preferido. También tenga en cuenta que el autocargador traduce ambos separadores de espacio de nombres y subraya _ como un separador de directorio. Así que su Front_controller.php no se Front_controller.php automáticamente como esperaría.

De hecho, estoy intentando crear un marco MVC para mí, sin embargo, estoy teniendo problemas con la carga automática. No es un problema en realidad, pero me gustaría preguntar a los gurús, ¿cómo están usando la función spl_autoload_register cuando hay diferentes directorios?

Digamos que tenemos los siguientes directorios:

Controllers Libs Models

Cada carpeta contiene diferentes clases, como:

Controllers: Main.php File.php About.php Libs: Main.php Front_controller.php Models: Index.php File.php Login.php

Puede observar que algunos nombres de archivo pueden encontrarse con el mismo nombre en directorios diferentes. Bien, esto es lo que he intentado hasta ahora:

spl_autoload_register(function ($class) { $pathContorllers = ''Controllers/'' . $class . ''.php''; $pathLibs = ''Libs/'' . $class . ''.php''; $pathModels = ''Models/'' . $class . ''.php''; if (file_exists($pathContorllers)) { require_once $pathContorllers; } elseif (file_exists($pathLibs)) { require_once $pathLibs; } elseif (file_exists($pathModels )) { require_once $pathModels ; } });

Está funcionando bien, sin embargo, estoy seguro de que hay otra manera de simplificar todo. ¿Alguien puede sugerirme cómo puedo mejorar o simplificar este código? ¿Qué están utilizando los gurús en esta situación?


El código de abajo te ayudará. Pero te aconsejo que compruebes los espacios de nombres.

spl_autoload_register ( function ($class) { $sources = array("Controllers/$class.php", "Lib/$class.php ", "Models/$class.php " ); foreach ($sources as $source) { if (file_exists($source)) { require_once $source; } } });