electricas - Estrategias de carga y nomenclatura de PHP eficientes
variables electricas (3)
Aterricé en esta solución:
Creé un único script que atraviesa mi carpeta de biblioteca de clase (que contiene subcarpetas para módulos / sistemas separados) y analiza el contenido del archivo buscando definiciones de clase. Si encuentra una definición de clase en un archivo php (patrón regex bastante simple), crea un enlace simbólico:
class_name.php -> actual/source/file.php
Esto me permite usar una función de autocarga única y simple que solo necesita el nombre de clase y la ruta a la carpeta principal de enlace simbólico, y no tiene que hacer ninguna manipulación de ruta / cadena.
La mejor parte es que puedo reorganizar mi código fuente por completo o agregar un nuevo subsistema y simplemente ejecutar el script de generación de enlaces para tener todo cargado automáticamente.
Al igual que la mayoría de los desarrolladores web en estos días, estoy disfrutando plenamente de los beneficios de la sólida arquitectura MVC para aplicaciones y sitios web. Al hacer MVC con PHP, la carga automática obviamente es extremadamente útil.
Me he hecho fanático de spl_autoload_register
simplemente por definir una sola __autoload()
, ya que obviamente es más flexible si está incorporando diferentes módulos base que cada uno usa su propia carga automática. Sin embargo, nunca me he sentido bien con las funciones de carga que escribo. Implican una gran cantidad de comprobación de cadenas y escaneo de directorios para buscar posibles clases para cargar.
Por ejemplo, supongamos que tengo una aplicación que tiene una ruta base definida como PATH_APP
, y una estructura simple con directorios llamados models
, views
y controllers
. A menudo utilizo una estructura de nombres por la cual los archivos se denominan IndexView.php
e IndexController.php
dentro del directorio apropiado, y los modelos generalmente no tienen un esquema particular por defecto. Es posible que tenga una función de cargador para esta estructura como esta que se registra con spl_autoload_register
:
public function MVCLoader($class)
{
if (file_exists(PATH_APP.''/models/''.$class.''.php'')) {
require_once(PATH_APP.''/models/''.$class.''.php'');
return true;
}
else if (strpos($class,''View'') !== false) {
if (file_exists(PATH_APP.''/views/''.$class.''.php'')) {
require_once(PATH_APP.''/views/''.$class.''.php'');
return true;
}
}
else if (strpos($class,''Controller'') !== false) {
if (file_exists(PATH_APP.''/controllers/''.$class.''.php'')) {
require_once(PATH_APP.''/controllers/''.$class.''.php'');
return true;
}
}
return false;
}
Si no se encuentra después de eso, podría tener otra función para escanear los subdirectorios en el directorio de modelos. Sin embargo, todo el análisis if / else -ing, la verificación de cadenas y el escaneo de directorios me parece ineficiente, y me gustaría mejorarlo.
Tengo mucha curiosidad sobre qué nombres de archivos y estrategias de carga automática pueden emplear otros desarrolladores. Estoy buscando específicamente buenas técnicas para emplear para la carga automática eficiente, y no alternativas a la carga automática.
Esto es lo que he estado usando en todos mis proyectos (tomado directamente de la fuente del último):
public static function loadClass($class)
{
$files = array(
$class . ''.php'',
str_replace(''_'', ''/'', $class) . ''.php'',
);
foreach (explode(PATH_SEPARATOR, ini_get(''include_path'')) as $base_path)
{
foreach ($files as $file)
{
$path = "$base_path/$file";
if (file_exists($path) && is_readable($path))
{
include_once $path;
return;
}
}
}
}
Si busco SomeClass_SeperatedWith_Underscores buscará SomeClass_SeperatedWith_Underscores.php seguido de SomeClass / SeperatedWith / Underscores.php enrutado en cada directorio en la ruta actual de inclusión.
EDITAR: Solo quería decir que uso esto para la eficiencia en el desarrollo, y no necesariamente para el tiempo de procesamiento. Si tiene PEAR en su camino, puede usar las clases y no tiene que incluirlas cuando las necesite.
Tiendo a mantener mis clases en una jerarquía de directorios, con guiones bajos que rompen espacios de nombres ... Este código me permite mantener la estructura de archivos limpia y ordenada si quiero, o inyectar un archivo de clase rápido sin directorios anidados si quiero (para agregando una sola clase o dos a una biblioteca de la que está acusado, pero que no forma parte del proyecto en el que estoy trabajando actualmente).
Si desea eficiencia, no debe utilizar la función de autocarga. La función de autocarga es para ser flojo. Debería proporcionar una ruta de acceso explícita a sus archivos de inclusión cuando los incluya. Si la función de autocarga puede encontrar estos archivos, puede codificar para encontrarlos de manera explícita. Cuando trabajas en la parte de vista del código y estás a punto de cargar una nueva clase de vista, al dejar que la función de autocarga lo maneje, primero asume que tu clase es una clase de modelo. Eso es ineficiente. En cambio, su código debería ser:
include_once $this->views_path . $class . ''.php'';
Si necesita varias rutas de "vista", realice una función que cargue vistas:
public function load_view($class) {
// perhaps there''s a mapping here instead....
foreach ($this->views_paths as $path) {
$filename = $path . $class . ''.php'';
if (file_exists($filename)) {
include_once $filename;
}
}
throw ....
}
En cualquier caso, en el punto donde ocurre la inclusión, tiene la información más grande / más precisa sobre la clase que desea cargar. Usar esa información para cargar la clase por completo es la única estrategia eficiente de carga de clases. Sí, puedes terminar con más variables de clase o (cielo no lo permita) algunas variables globales. Pero esa es una mejor solución que simplemente ser flojo y escanear partes del sistema de archivos para su clase.