自动加载

妖狐艹你老母 2023-02-28 05:26 336阅读 0赞

类自动加载

在编写面向对象程序时,每个类新建一个PHP文件,这会带来一个烦恼:每个脚本的开头,都需要require一个长长的列表。这就需要一种自动加载机制。

所谓类自动加载就是当我们想使用某个命名空间下的某个类时,直接use某个类,然后在使用这个类时自动按照某个规则将文件require,不用自己显示的require相应的代码文件。我们在使用一些开源框架时,一般都引入了类自动加载。

在PHP早期版本中通过__autoload()函数完成自动加载,在PHP5以后,官方推荐使用spl_autoload_register()函数实现类自动加载,spl_autoload_register()函数可以注册任意数量的自动加载器,当使用尚未被定义的类时自动去加载。

关于类自动加载也是有一定规范的,PSR-4规定了类自动加载的规范。

1. psr-4

PSR-4关于类自动加载的规范如下:

  • 1.The term “class” refers to classes, interfaces, traits, and other similar structures.
  • 2.A fully qualified class name has the following form:

    1. \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>

    1.The fully qualified class name MUST have a top-level namespace name, also known as a “vendor namespace”.

    2.The fully qualified class name MAY have one or more sub-namespace names.

    3.The fully qualified class name MUST have a terminating class name.

    4.Underscores have no special meaning in any portion of the fully qualified class name.

    5.Alphabetic characters in the fully qualified class name MAY be any combination of lower case and upper case.

    6.All class names MUST be referenced in a case-sensitive fashion.

  • 3.When loading a file that corresponds to a fully qualified class name …

1.A contiguous series of one or more leading namespace and sub-namespace names, not including the leading namespace separator, in the fully qualified class name (a “namespace prefix”) corresponds to at least one “base directory”.

2.The contiguous sub-namespace names after the “namespace prefix” correspond to a subdirectory within a “base directory”, in which the namespace separators represent directory separators. The subdirectory name MUST match the case of the sub-namespace names.

3.The terminating class name corresponds to a file name ending in .php. The file name MUST match the case of the terminating class name.

  • 4.Autoloader implementations MUST NOT throw exceptions, MUST NOT raise errors of any level, and SHOULD NOT return a value.

2. 实现

因为作者是Yii2的严重用户,所以习惯性将命名空间和目录对应,且目录全部使用小写字母,一个符合PSR-4规范的自动加载类如下:

  1. /** * Class Autoload * @datetime 2020/6/29 11:27 上午 * @author roach * @email jhq0113@163.com */
  2. class Autoload
  3. {
  4. private function __construct()
  5. {
  6. }
  7. private function __clone()
  8. {
  9. // TODO: Implement __clone() method.
  10. }
  11. /** * @var array * @datetime 2020/6/24 10:10 上午 * @author roach * @email jhq0113@163.com */
  12. private static $_namespace = [];
  13. /**注册一个命名空间前缀 * @param string $prefix * @param string $dir * @datetime 2020/6/24 10:10 上午 * @author roach * @email jhq0113@163.com */
  14. public static function set($prefix, $dir)
  15. {
  16. self::$_namespace[ $prefix ] = $dir;
  17. }
  18. /**注册多个命名空间前缀 * @param array $namespaceArray * @datetime 2020/6/24 10:14 上午 * @author roach * @email jhq0113@163.com */
  19. public static function mset($namespaceArray = [])
  20. {
  21. foreach ($namespaceArray as $prefix => $dir) {
  22. self::$_namespace[ $prefix ] = $dir;
  23. }
  24. }
  25. /** * @param string $class * @datetime 2020/6/24 10:15 上午 * @author roach * @email jhq0113@163.com */
  26. public static function autoload($class)
  27. {
  28. $position = strpos($class,'\\');
  29. $prefix = substr($class, 0, $position);
  30. if(!isset(self::$_namespace[ $prefix ])) {
  31. return;
  32. }
  33. $fileName = self::$_namespace[ $prefix ].str_replace('\\','/', substr($class, $position)).'.php';
  34. if(file_exists($fileName)) {
  35. require $fileName;
  36. }
  37. }
  38. }

在单入口应用当中,在你的入口文件index.php中添加如下代码即可完成自动加载。

  1. <?php
  2. //引入自动加载类文件
  3. require __DIR__.'/Autoload.php';
  4. //注册自动加载函数
  5. spl_autoload_register('Autoload::autoload');
  6. //注册命名空间前缀
  7. Autoload::set('library', dirname(__DIR__).'/library');

PHP依赖管理工具composer会自带一个符合PSR-4规范的类自动加载器,如果我们的项目是使用composer管理依赖的,我们可以直接使用composer的类自动加载器。

学习更多内容: https://404.360tryst.com

我的视频课程: https://edu.csdn.net/course/detail/9933

发表评论

表情:
评论列表 (有 0 条评论,336人围观)

还没有评论,来说两句吧...

相关阅读

    相关 php 自动机制

    一、基础了解。     1、php引入文件使用include与require,这两个的区别在于,include可以在代码执行过程中再引入,而require是需要在代码执行前就

    相关 自动

    类自动加载 > 在编写面向对象程序时,每个类新建一个PHP文件,这会带来一个烦恼:每个脚本的开头,都需要`require`一个长长的列表。这就需要一种自动加载机制。 >

    相关 Vue自动路由

    每次创建页面之后,都需要手动引入模块,创建路由,很麻烦。 这里使用webpack中的require.context来实现创建页面之后,自动加载路由。 同时,因为编写加载