otro - La mejor manera de autocargar clases en PHP
php class constructor (5)
Aquí tengo un ejemplo que utilizo para la carga automática y la activación.
Básicamente, una mejor versión de spl_autoload_register, ya que solo intenta requerir el archivo de clase cada vez que inicializa la clase.
Aquí obtiene automáticamente todos los archivos dentro de su carpeta de clase, requiere los archivos y los inicializa. Todo lo que tienes que hacer, es nombrar la clase igual que el archivo.
index.php
<?php
require_once __DIR__ . ''/app/autoload.php'';
$loader = new Loader(false);
User::dump([''hello'' => ''test'']);
autoload.php
<?php
class Loader
{
public static $library;
protected static $classPath = __DIR__ . "/classes/";
protected static $interfacePath = __DIR__ . "/classes/interfaces/";
public function __construct($requireInterface = true)
{
if(!isset(static::$library)) {
// Get all files inside the class folder
foreach(array_map(''basename'', glob(static::$classPath . "*.php", GLOB_BRACE)) as $classExt) {
// Make sure the class is not already declared
if(!in_array($classExt, get_declared_classes())) {
// Get rid of php extension easily without pathinfo
$classNoExt = substr($classExt, 0, -4);
$file = static::$path . $classExt;
if($requireInterface) {
// Get interface file
$interface = static::$interfacePath . $classExt;
// Check if interface file exists
if(!file_exists($interface)) {
// Throw exception
die("Unable to load interface file: " . $interface);
}
// Require interface
require_once $interface;
//Check if interface is set
if(!interface_exists("Interface" . $classNoExt)) {
// Throw exception
die("Unable to find interface: " . $interface);
}
}
// Require class
require_once $file;
// Check if class file exists
if(class_exists($classNoExt)) {
// Set class // class.container.php
static::$library[$classNoExt] = new $classNoExt();
} else {
// Throw error
die("Unable to load class: " . $classNoExt);
}
}
}
}
}
/*public function get($class)
{
return (in_array($class, get_declared_classes()) ? static::$library[$class] : die("Class <b>{$class}</b> doesn''t exist."));
}*/
}
Puede administrar fácilmente con un poco de codificación, para requerir clases en diferentes carpetas también.
Esperemos que esto pueda ser de alguna utilidad para usted.
Estoy trabajando en un proyecto en el que tengo la siguiente estructura de archivos:
index.php
|---lib
|--|lib|type|class_name.php
|--|lib|size|example_class.php
Me gustaría cargar automáticamente las clases, class_name y example_class (con el mismo nombre que las clases de PHP), para que en index.php las clases ya estén instanciadas, así que podría hacer:
$class_name->getPrivateParam(''name'');
He echado un vistazo en la red, pero no puedo encontrar la respuesta correcta. ¿Puede alguien ayudarme?
EDITAR
Gracias por las respuestas. Déjame expandir en mi escenario. Estoy tratando de escribir un complemento de WordPress que se puede colocar en un proyecto y se puede agregar una funcionalidad adicional al colocar una clase en una carpeta ''funcionalidad'', por ejemplo, dentro del complemento. ¿Nunca habrá 1000 clases, en un impulso tal vez 10?
Podría escribir un método para iterar a través de la estructura de carpetas de la carpeta ''lib'', incluidas todas las clases y luego asignarlo a una variable (del nombre de la clase), pero no pensé que fuera una forma muy eficiente de hacerlo, pero Tal vez parece que esa es la mejor manera de lograr lo que necesito?
Por favor, si necesita autocargar las clases, use los espacios de nombres y las convenciones de los nombres de las clases con SPL autoload, le ahorrará tiempo para la refactorización. Y, por supuesto, deberá crear una instancia de cada clase como un objeto. Gracias.
Al igual que en este hilo: PHP Autoloading en espacios de nombres
Pero si quieres una solución compleja, echa un vistazo a la clase de carga automática de Symfony: https://github.com/symfony/ClassLoader/blob/master/ClassLoader.php
O así (lo hice en uno de mis proyectos):
<?
spl_autoload_register(function($className)
{
$namespace=str_replace("//","/",__NAMESPACE__);
$className=str_replace("//","/",$className);
$class=CORE_PATH."/classes/".(empty($namespace)?"":$namespace."/")."{$className}.class.php";
include_once($class);
});
?>
y luego puedes crear una instancia de tu clase como esta:
<?
$example=new NS1/NS2/ExampleClass($exampleConstructParam);
?>
y esta es su clase (que se encuentra en /NS1/NS2/ExampleClass.class.php):
<?
namespace NS1/NS2
{
class Symbols extends /DB/Table
{
public function __construct($param)
{
echo "hello!";
}
}
}
?>
Si tiene acceso a la línea de comandos, puede intentarlo con el compositor en la sección classMap con algo como esto:
{
"autoload": {
"classmap": ["yourpath/", "anotherpath/"]
}
}
entonces tienes un plugin de wordpress para habilitar compositor en el wordpress cli: http://wordpress.org/plugins/composer/
http://php.net/manual/de/function.spl-autoload-register.php
spl_autoload_register(function ($class) {
@require_once(''lib/type/'' . $class . ''.php'');
@require_once(''lib/size/'' . $class . ''.php'');
});
function __autoload($class_name) {
$class_name = strtolower($class_name);
$path = "{$class_name}.php";
if (file_exists($path)) {
require_once($path);
} else {
die("The file {$class_name}.php could not be found!");
}
}
ACTUALIZACIÓN: __autoload()
está en desuso a partir de PHP 7.2