Maison  >  Article  >  développement back-end  >  Résumé de l'application du chargement automatique et de l'espace de noms de PHP

Résumé de l'application du chargement automatique et de l'espace de noms de PHP

不言
不言original
2018-04-19 14:16:271592parcourir

Laissez-moi d'abord vous dire ce qu'est un espace de noms.

"Qu'est-ce qu'un espace de noms ? D'une manière générale, un espace de noms est une façon d'encapsuler des choses. Ce concept abstrait peut être vu à de nombreux endroits. Par exemple, dans les systèmes d'exploitation, les répertoires sont utilisés pour regrouper les fichiers liés. Pour les répertoires Pour les fichiers, il joue le rôle d'un espace de noms. Par exemple, les fichiers. foo.txt peut exister dans les répertoires /home/greg et /home/other en même temps, mais deux foo.txt ne peuvent pas exister dans le même répertoire document. De plus, lors de l'accès au fichier foo.txt en dehors du répertoire /home/greg, nous devons mettre le nom du répertoire et le séparateur de répertoire avant le nom du fichier pour obtenir /home/greg/foo.txt. L'application de ce principe au domaine de la programmation est le concept d'espace de noms. »

Le chargement automatique de PHP signifie que lorsque nous chargeons une classe instanciée, nous n'avons pas besoin d'écrire manuellement require pour importer le fichier class.php. Le programme le charge et l'importe automatiquement pour nous. Avec la spécification de l'espace de noms, nous pouvons facilement gérer le chargement et l'appel de différentes classes dans des systèmes complexes.

1. Le principe du chargement automatique et l'utilisation de __autoload

Le principe du chargement automatique est que lorsque l'on instancie une classe, si PHP ne trouve pas la classe, il appellera automatiquement le Méthode __autoload($class_name), notre nouveau class_name Cela devient le paramètre de cette méthode. Nous pouvons donc utiliser du nouveau dans cette méthode selon nos besoins Divers jugements et divisions de class_name nécessitent le fichier de classe de chemin correspondant pour réaliser un chargement automatique.

Regardons d'abord l'appel automatique de __autoload(), à titre d'exemple :

index.php

<?php 
$db = new Db();

Si nous n'importons pas la classe Db manuellement, le programme peut signaler une erreur indiquant que cette classe est introuvable :

Erreur fatale : erreur non détectée : classe « DB » introuvable dans D:webhellowebademo2017autoloadindex.php:2 Trace de pile : #0 {main} lancé dans D:webhellowebademo2017autoloadindex.php en ligne 2

Alors, ajoutons maintenant la méthode __autoload() et jetons un œil :

$db = new DB();
function __autoload($className) {
 echo $className;
 exit();
}

Selon la description du mécanisme de chargement automatique ci-dessus, le résultat sera : Db, qui est le nom de la classe dont nous avons besoin. Par conséquent, à ce stade, nous pouvons charger le fichier de bibliothèque de classes selon les besoins dans la méthode __autoload().

2. spl_autoload_register se charge automatiquement

S'il s'agit d'un petit projet, utilisez __autoload() Un chargement automatique de base peut être réalisé. Mais si un projet est très volumineux ou si un chargement automatique différent est requis pour charger des fichiers avec des chemins différents, alors __autoload sera inutile car un seul est autorisé dans un projet. Fonction __autoload(), car PHP n'autorise pas les fonctions avec des noms en double, ce qui signifie que vous ne pouvez pas déclarer deux __autoload() fichier de fonction, sinon une erreur fatale sera signalée. Ce qu'il faut faire? Ne vous inquiétez pas, quoi que vous pensiez, le maître PHP y a déjà pensé. Donc spl_autoload_register() De cette façon, une autre fonction géniale est née et l'a remplacé. Il fonctionne plus efficacement et est plus flexible.

Voyons d'abord comment l'utiliser. Ajoutez le code suivant à index.php.

<?php 
spl_autoload_register(function($className){
 if (is_file(&#39;./Lib/&#39; . $className . &#39;.php&#39;)) {
 require &#39;./Lib/&#39; . $className . &#39;.php&#39;;
 }
});
$db = new Db();
$db::test();

Ajoutez le code suivant au fichier LibDb.php :

<?php 
class Db
{
 public static function test()
 {
 echo &#39;Test&#39;;
 }
}

Après avoir exécuté index.php, lorsque new Db() est appelé, spl_autoload_register Il ira automatiquement dans le répertoire lib/ pour trouver le fichier Db.php correspondant. Après succès, $db::test(); . De même, s'il y a plusieurs fichiers de classe php dans le répertoire Lib, ils peuvent être appelés directement dans index.php sans nécessiter plusieurs fichiers.

En d'autres termes, spl_autoload_register peut être réutilisé plusieurs fois. Cela résout les défauts de __autoload. Ensuite, si une page a plusieurs spl_autoload_registers, l'ordre d'exécution est dans l'ordre d'enregistrement. Si trouvé, arrêtez-vous.

3. spl_autoload_register chargement automatique et espace de noms

Pour les systèmes très complexes, la structure des répertoires sera également très complexe. L'espace de noms standardisé résout le problème d'un grand nombre de fichiers, de fonctions et de classes avec des noms en double sous des chemins complexes. Le chargement automatique est désormais la pierre angulaire des frameworks PHP modernes, essentiellement spl_autoload_register pour implémenter le chargement automatique. Donc spl_autoload_register + espace de noms C’est devenu un courant dominant.

Selon la série de spécifications PSR, la dénomination des espaces de noms a été très standardisée, de sorte que le chemin détaillé peut être trouvé en fonction de l'espace de noms pour trouver le fichier de classe.

Nous utilisons l'exemple le plus simple pour illustrer comment des systèmes complexes chargent automatiquement les fichiers de classe.

Tout d'abord, nous préparons la structure des répertoires système :

----/Lib  // 类目录
 --Db.php
 --Say.php
----autoload.php // 自动加载函数
----index.php // 首页

Ce qui précède est un répertoire système de base. Ce que nous voulons réaliser, c'est utiliser l'espace de noms et le chargement automatique pour appeler directement plusieurs classes dans le répertoire Lib sur la page d'accueil index.php.

Nous préparons deux fichiers colonnes :

Db.php

<?php 
namespace Lib;
class Db
{
 public function __construct()
 {
 //echo &#39;Hello Db&#39;;
 }
 public static function test()
 {
 echo &#39;Test&#39;;
 }
}
Say.php
<?php
namespace Lib;
class Say 
{
 public function __construct()
 {
 //echo &#39;Hello&#39;;
 }
 public function hello()
 {
 echo &#39;say hello&#39;;
 }
}

以上两个普通的类文件,添加了命名空间: namespace Lib; 表示该类文件属于Lib目录名称下的,当然你可以随便取个不一样的名字来表示你的项目名称。

现在我们来看autoload.php:

<?php 
spl_autoload_register(function ($class) {
 $prefix = &#39;Lib\\&#39;;
 $base_dir = __DIR__ . &#39;/Lib/&#39;;
 // does the class use the namespace prefix?
 $len = strlen($prefix);
 if (strncmp($prefix, $class, $len) !== 0) {
 // no, move to the next registered autoloader
 return;
 }
 $relative_class = substr($class, $len);
 // 兼容Linux文件找。Windows 下(/ 和 \)是通用的
 $file = $base_dir . str_replace(&#39;\\&#39;, &#39;/&#39;, $relative_class) . &#39;.php&#39;;
 if (file_exists($file)) {
 require $file;
 }
});

以上代码使用函数 spl_autoload_register() 首先判断是否使用了命名空间,然后验证要调用的类文件是否存在,如果存在就 require 类文件。

好了,现在我们在首页index.php这样调用:

<?php 
use Lib\Db;
use Lib\Say;
require &#39;./autoload.php&#39;;
$db = new Db();
$db::test();
$say = new Say;
$say->hello();

我们只需使用一个require将autoload.php加载进来,使用 use 关键字将类文件路径变成绝对路径了,当然你也可以在调用类的时候把路径都写上,如: new LibDb(); ,但是涉及到多个类互相调用的时候就会很棘手,所以我们还是在文件开头就使用 use 把路径处理好。

接下来就直接调用Lib/目录下的各种类文件了,你可以在Lib/目录下放置多个类文件尝试下。

运行index.php看看是不是如您所愿。

结束语

该文简单介绍了自动加载以及命名空间的使用,实际开发中,我们很少去关注autoload自动加载的问题,因为大多数现代PHP框架都已经处理好了文件自动加载的问题。开发者只需关注业务代码,使用规范的命名空间就可以了。当然,如果你想自己开发个项目不依赖大型框架亦或者自己开发php框架,那你就得熟悉下autoload自动加载这个好东西了,毕竟它可以让我们“偷懒”,省事多了。

现代php里,我们经常使用 Composer 方式安装的组件,都可以通过autoload实现自动加载,所以还是一个“懒”字给我们带来了极好的开发效率。


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn