Dans le développement de PHP moderne, les mécanismes de chargement automatiques sont devenus une partie indispensable. Via spl_autoload_register () , nous pouvons introduire automatiquement des fichiers correspondants lorsque la classe n'est pas définie, en évitant un grand nombre d'appels requises ou inclut . Cependant, dans certains cas, nous voulons déterminer immédiatement après le chargement de la classe s'il appartient à un certain type (comme une classe de base ou la mise en œuvre d'une interface), qui peut obtenir un jugement de type de chargement automatique avec IS_A () .
Cet article présentera comment combiner SPL_autoload_register () et is_a () pour effectuer une vérification du type de classe pendant le chargement automatique pour améliorer la robustesse et la maintenabilité du code.
spl_autoload_register () nous permet d'enregistrer une ou plusieurs fonctions Autoload. Chaque fois qu'une classe non définie est tentée, PHP appelle ces fonctions pour essayer de charger la définition de la classe.
L'exemple de code est le suivant:
spl_autoload_register(function ($class) {
$path = __DIR__ . '/classes/' . $class . '.php';
if (file_exists($path)) {
require_once $path;
}
});
Le code ci-dessus recherchera des fichiers PHP qui correspondent au nom de classe dans le répertoire des classes .
Dans certains scénarios, il ne suffit pas de charger des cours. Nous voulons également savoir si la classe est une sous-classe d'une classe de base ou implémente une interface. Pour le moment, vous pouvez utiliser IS_A () pour faire des jugements:
if (class_exists($class) && is_a($class, 'SomeInterface', true)) {
// $class Oui SomeInterface Classe d'implémentation
}
Notez que le troisième paramètre ici est défini sur true , ce qui signifie "permet d'utiliser des chaînes comme noms de classe sans nécessiter une instanciation réelle".
Ci-dessous, nous écrivons un chargeur automatique complet, qui détermine automatiquement si la classe est un type spécifié après le chargement:
spl_autoload_register(function ($class) {
$baseDir = __DIR__ . '/classes/';
$file = $baseDir . $class . '.php';
if (file_exists($file)) {
require_once $file;
if (!is_a($class, 'App\\Contracts\\ServiceInterface', true)) {
throw new Exception("gentil {$class} Doit être atteint App\\Contracts\\ServiceInterface interface。");
}
} else {
throw new Exception("无法加载gentil {$class},Le fichier n'existe pas。");
}
});
Dans cet exemple, nous supposons que toutes les classes de service doivent implémenter l'interface App \ Contracts \ ServiceInterface . Si une classe n'implémente pas l'interface, une exception est lancée.
Pour vérifier le code ci-dessus, nous pouvons créer la classe de classe et d'interface suivante:
// Chemin de fichier:classes/MyService.php
namespace App\Services;
use App\Contracts\ServiceInterface;
class MyService implements ServiceInterface {
public function handle() {
echo "Gérer la logique commerciale";
}
}
// Chemin de fichier:classes/App/Contracts/ServiceInterface.php
namespace App\Contracts;
interface ServiceInterface {
public function handle();
}
Ensuite, utilisez-le dans le programme principal:
use App\Services\MyService;
$service = new MyService();
$service->handle();
Lorsque nous instancions MyService , l'autoloader chargera la classe et vérifiera s'il implémente ServiceInterface . S'il n'est pas mis en œuvre, une exception sera lancée.
En combinant SPL_autoload_register () et IS_A () , nous pouvons implémenter un mécanisme de chargement automatique plus robuste. Il permet non seulement de charger dynamiquement les fichiers de classe, mais vous permet également de vérifier que son type répond aux attentes immédiatement après le chargement du cours. Cette approche est idéale pour les scénarios où des contraintes de type solides sont nécessaires dans le développement du framework, la gestion du plug-in ou les architectures de grand système.