介绍PHP的自动加载

昨天面试被问到了 PHP 的自动加载机制,因为很多概念模糊啦,没回答好,今天特意来总结一下。

include 和 require 是PHP中引入文件的两个基本方法,但是每个脚本的开头,都需要包含(include)一个长长的列表总是不好的,所以 PHP 使用了自动加载器来解决这个问题。

PHP 自动加载

实现自动加载的两种方式

  •  __autoload() 尝试加载未定义的类(因为只可以定义一次,不再建议使用 __autoload() 函数,在以后的版本中它可能被弃用
  • spl_autoload_register() 提供了一种更加灵活的方式来实现类的自动加载(同一个应用中,支持任意数量的加载器,比如第三方库中的)。

spl_autoload_register 方式

功能:就是把传入的参数(可以为回调函数或函数名称)注册到 SPL __autoload 函数队列中。如果在你的程序中已经实现了 __autoload 函数,它必须显式注册到队列中。(PHP 5 >= 5.1.0, PHP 7)

参数介绍:

  • autoload_function:回调函数或者函数名称形式,如果没有提供任何参数,则自动注册 autoload 的默认实现函数。
  • throw: autoload_function 无法成功注册时, spl_autoload_register()是否抛出异常。
  • prepend:如果是 true,spl_autoload_register() 会添加函数到队列之首,而不是队列尾部。
 1 <?php
 2 namespace Foobar;
 3 
 4 class Foo {
 5     static public function test($name) {
 6         print '[['. $name .']]';
 7     }
 8 }
 9 spl_autoload_register(__NAMESPACE__ .'Foo::test'); // 自 PHP 5.3.0 起
10 
11 new InexistentClass;
12 
13 ?>
输出示例:
[[FoobarInexistentClass]]
Fatal error: Class 'FoobarInexistentClass' not found in ...

上述代码:将 Foo 的静态方法 test 注册到自动加载队列中,通过上面的示例可以看到 自动加载的运行过程,既:当需要使用的类没有被引入时,这个函数会在PHP报错前被触发

函数里面的具体逻辑要根据我们的具体情况实现,就上面的问题而言,引入的函数需要同样在 Foobar 的命名空间之下,并且声明 InexistentClass 对象。(PSR-4 是关于由文件路径自动载入对应类的相关规范)。

PHP 中 USE 关键字介绍

use 关键字作用

为类名称使用别名、为接口使用别名或为命名空间名称使用别名。PHP 5.6开始允许导入函数或常量或者为它们设置别名。

PHP 7 可以使用一个 use 从同一个 namespace 中导入类、函数和常量。

 1 // PHP 7 之前版本需要使用多次 use 
 2 use some
amespaceClassA; 
 3 use some
amespaceClassB; 
 4 use some
amespaceClassC as C; 
 5 
 6 use function some
amespacefn_a; 
 7 use function some
amespacefn_b; 
 8 use function some
amespacefn_c; 
 9 
10 use const some
amespaceConstA; 
11 use const some
amespaceConstB; 
12 use const some
amespaceConstC; 
13 
14 // PHP 7+ 之后版本可以使用一个 use 导入同一个 namespace 的类 
15 use some
amespace{ClassA, ClassB, ClassC as C}; 
16 use function some
amespace{fn_a, fn_b, fn_c}; 
17 use const some
amespace{ConstA, ConstB, ConstC}; 
18 ?>
PHP 使用 USE

执行流程

use 关键字并不是立刻导入所 use 的类,它只是声明某类的完整类名(命名空间::类标示符),而后你在上下文中使用此类时系统才会根据 use 声明获取此类的完整类名 然后利用自动加载机制进行载入。

具体例子

 1 <?php
 2 use PsrHttpMessageServerRequestInterface as Request;
 3 use PsrHttpMessageResponseInterface as Response;
 4 require 'vendor/autoload.php';
 5 
 6 $app = new SlimApp;
 7 $app->get('/hello/{name}', function (Request $request, Response $response) {
 8     $name = $request->getAttribute('name');
 9     $response->getBody()->write("Hello, $name");
10     return $response;
11 });
12 $app->run();

就像如上的代码 自动载入函数是在 use 两个类之后方才实现的 因为 use 并不会立即使用此类 只有在你调用此类时系统才会在找不到此类的情况下通过 autoload 函数动态延迟加载,若仍加载不到,则报错。

参考

PHP 命名空间与自动加载机制介绍

PHP 命名空间 namespace / 类别名 use / 框架自动载入 机理的 

原文地址:https://www.cnblogs.com/yweihum/p/9553532.html