PHP
Primer de carga automática
Buscar..
Sintaxis
- exigir
- spl_autoload_require
Observaciones
La carga automática, como parte de una estrategia de marco, facilita la cantidad de código repetitivo que tiene que escribir.
Definición de clase en línea, no requiere carga
// zoo.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
$animal = new Animal();
$animal->eats('meat');
PHP sabe qué es Animal
antes de ejecutar el new Animal
, porque PHP lee los archivos de origen de arriba a abajo. Pero, ¿y si quisiéramos crear nuevos animales en muchos lugares, no solo en el archivo de origen donde está definido? Para hacer eso, necesitamos cargar la definición de la clase.
Carga manual de clases con requerimiento.
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// zoo.php
require 'Animal.php';
$animal = new Animal;
$animal->eats('slop');
// aquarium.php
require 'Animal.php';
$animal = new Animal;
$animal->eats('shrimp');
Aquí tenemos tres archivos. Un archivo ("Animal.php") define la clase. Este archivo no tiene efectos secundarios además de definir la clase y mantiene perfectamente todo el conocimiento sobre un "Animal" en un solo lugar. Es fácilmente versión controlada. Es fácilmente reutilizable.
Dos archivos consumen el archivo "Animal.php" al require
manualmente el archivo. Nuevamente, PHP lee los archivos de origen de arriba a abajo, por lo que el servicio requiere el archivo "Animal.php" y hace que la definición de la clase Animal
esté disponible antes de llamar al new Animal
.
Ahora imagine que tuvimos docenas o cientos de casos en los que queríamos realizar un new Animal
. Eso requeriría (destinado a los juegos de palabras) muchos, muchos require
declaraciones que son muy tediosas para codificar.
La carga automática reemplaza la carga de definición de clase manual
// autoload.php
spl_autoload_register(function ($class) {
require_once "$class.php";
});
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// zoo.php
require 'autoload.php';
$animal = new Animal;
$animal->eats('slop');
// aquarium.php
require 'autoload.php';
$animal = new Animal;
$animal->eats('shrimp');
Compara esto con los otros ejemplos. Observe cómo se reemplazó require "Animal.php"
con require "autoload.php"
. Todavía estamos incluyendo un archivo externo en tiempo de ejecución, pero en lugar de incluir una definición de clase específica , incluimos una lógica que puede incluir cualquier clase. Es un nivel de direccionamiento que facilita nuestro desarrollo. En lugar de escribir un require
para cada clase que necesitamos, escribimos un require
para todas las clases. Podemos reemplazar N require
con 1 require
.
La magia sucede con spl_autoload_register . Esta función de PHP se cierra y agrega el cierre a una cola de cierres. Cuando PHP encuentra una clase para la que no tiene definición, PHP entrega el nombre de la clase a cada cierre en la cola. Si la clase existe después de llamar a un cierre, PHP vuelve a su negocio anterior. Si la clase no existe después de probar toda la cola, PHP se bloquea con "No se encontró la clase 'Lo que sea'".
Autocarga como parte de una solución marco
// autoload.php
spl_autoload_register(function ($class) {
require_once "$class.php";
});
// Animal.php
class Animal {
public function eats($food) {
echo "Yum, $food!";
}
}
// Ruminant.php
class Ruminant extends Animal {
public function eats($food) {
if ('grass' === $food) {
parent::eats($food);
} else {
echo "Yuck, $food!";
}
}
}
// Cow.php
class Cow extends Ruminant {
}
// pasture.php
require 'autoload.php';
$animal = new Cow;
$animal->eats('grass');
Gracias a nuestro cargador automático genérico, tenemos acceso a cualquier clase que siga nuestra convención de nomenclatura del cargador automático. En este ejemplo, nuestra convención es simple: la clase deseada debe tener un archivo en el mismo directorio nombrado para la clase y que termina en ".php". Observe que el nombre de la clase coincide exactamente con el nombre del archivo.
Sin carga automática, tendríamos que require
manualmente las clases base. Si construyéramos un zoológico completo de animales, tendríamos miles de declaraciones de requisitos que podrían reemplazarse más fácilmente con un solo cargador automático.
En el análisis final, la carga automática de PHP es un mecanismo que lo ayuda a escribir menos código mecánico para que pueda concentrarse en resolver problemas de negocios. Todo lo que tiene que hacer es definir una estrategia que asigne el nombre de la clase al nombre del archivo . Puede rodar su propia estrategia de carga automática, como se hace aquí. O bien, puede utilizar cualquiera de los estándares que la comunidad de PHP ha adoptado: PSR-0 o PSR-4 . O bien, puede utilizar compositor para definir y administrar genéricamente estas dependencias.
Autocarga con compositor
Composer genera un archivo vendor/autoload.php
.
Simplemente puede incluir este archivo y obtendrá la carga automática de forma gratuita.
require __DIR__ . '/vendor/autoload.php';
Esto hace que trabajar con dependencias de terceros sea muy fácil.
También puede agregar su propio código al autocargador agregando una sección de carga automática a su composer.json
.
{
"autoload": {
"psr-4": {"YourApplicationNamespace\\": "src/"}
}
}
En esta sección se definen las asignaciones de carga automática. En este ejemplo, se trata de una asignación PSR-4 de un espacio de nombres a un directorio: el directorio /src
reside en la carpeta raíz de su proyecto, en el mismo nivel que el directorio /vendor
. Un ejemplo de nombre de archivo sería src/Foo.php
contiene una clase YourApplicationNamespace\Foo
.
Importante: después de agregar nuevas entradas a la sección de carga automática, debe volver a ejecutar el comando dump-autoload
para volver a generar y actualizar el archivo vendor/autoload.php
con la nueva información.
Además PSR-4
carga automática de PSR-4
, Composer también admite PSR-0
, classmap
y carga automática de files
. Vea la referencia de carga automática para más información.
Al incluir el archivo /vendor/autoload.php
, se devolverá una instancia del Compositor Autoloader. Puede almacenar el valor de retorno de la llamada de inclusión en una variable y agregar más espacios de nombres. Esto puede ser útil para las clases de carga automática en un conjunto de pruebas, por ejemplo.
$loader = require __DIR__ . '/vendor/autoload.php';
$loader->add('Application\\Test\\', __DIR__);