昨天面试被问到了 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() 会添加函数到队列之首,而不是队列尾部。
 <?php
namespace Foobar; class Foo {
static public function test($name) {
print '[['. $name .']]';
}
}
spl_autoload_register(__NAMESPACE__ .'\Foo::test'); // 自 PHP 5.3.0 起 new InexistentClass; ?>
输出示例:
[[Foobar\InexistentClass]]
Fatal error: Class 'Foobar\InexistentClass' not found in ...

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

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

PHP 中 USE 关键字介绍

use 关键字作用

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

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

 // PHP 7 之前版本需要使用多次 use
use some\namespace\ClassA;
use some\namespace\ClassB;
use some\namespace\ClassC as C; use function some\namespace\fn_a;
use function some\namespace\fn_b;
use function some\namespace\fn_c; use const some\namespace\ConstA;
use const some\namespace\ConstB;
use const some\namespace\ConstC; // PHP 7+ 之后版本可以使用一个 use 导入同一个 namespace 的类
use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};
?>

PHP 使用 USE

执行流程

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

具体例子

 <?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require 'vendor/autoload.php'; $app = new \Slim\App;
$app->get('/hello/{name}', function (Request $request, Response $response) {
$name = $request->getAttribute('name');
$response->getBody()->write("Hello, $name");
return $response;
});
$app->run();

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

参考

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

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

最新文章

  1. ShowDoc部署手册
  2. 从零开始,做一个NodeJS博客(一):Heroku上的最简NodeJS服务器
  3. CAST和CONVERT差别与联系
  4. (转载)IO-同步、异步、阻塞、非阻塞
  5. VK Cup 2012 Round 3 (Unofficial Div. 2 Edition)
  6. CF 118E Bertown roads 桥
  7. 15分钟学会git基本的操作命令
  8. 基于visual Studio2013解决面试题之1305字符串所有子集
  9. 大白菜U盘启动制作工具装机维护版V5.0–大白菜U盘下载中心
  10. jdk阅读xml文件
  11. Arcgis Engine OMD
  12. kafka的高可用和一致性探究
  13. laravel中with()方法,has()方法和whereHas()方法的区别
  14. 第三期分享:一款很好用的api文档生成器
  15. rcu-bp关键代码解读
  16. IntelliJ IDEA 常用插件
  17. Centos下启动和关闭MySQL
  18. PostgreSQL CPU占用100%性能分析及慢sql优化
  19. linux杀死进程方法
  20. 【Hibernate步步为营】--最后的集合映射

热门文章

  1. QQ空间那年今日 &amp; 人人过往的今天
  2. Fiori里花瓣的动画效果实现原理
  3. CDS view注解解析 - @Environment.systemField
  4. sql server:取当前时间前10分钟之内的数据 dateadd()
  5. T-SQL 基础 2
  6. umlの类图
  7. 【luogu P4113 [HEOI2012]采花】 假题解
  8. UITableView的plain样式下,取消区头停滞效果
  9. 【2018 ICPC焦作网络赛 K】Transport Ship(多重背包二进制优化)
  10. 牛客小白月赛2 I 艺 【归并思想】【离散化】