• 介绍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 / 框架自动载入 机理的 

  • 相关阅读:
    这个我过滤概述UIPickerView键盘处理
    父子控制器
    源码0501-10-掌握-单粒模式
    源码0501-07-GCD的基本使用
    源码0501-04-了解-线程的状态
    源码-0501-01-处理耗时操作
    源码03-02-10-导航控制器简单使用
    spring在ssh框架中到底起到什么作用
    ssh整合
    spring整合hibernate
  • 原文地址:https://www.cnblogs.com/yweihum/p/9553532.html
Copyright © 2020-2023  润新知