Drupal通过spl_autoload_register()注册类加载器实现自动加载:

  1. function _drupal_bootstrap_database() {
  2. // ... ....
  3. spl_autoload_register('drupal_autoload_class');
  4. spl_autoload_register('drupal_autoload_interface');
  5. }

再来看看类加载器是如何实现的?

  1. function drupal_autoload_interface($interface) {
  2. return _registry_check_code('interface', $interface);
  3. }
  4.  
  5. function drupal_autoload_class($class) {
  6. return _registry_check_code('class', $class);
  7. }
  8.  
  9. function _registry_check_code($type, $name = NULL) {
  10. static $lookup_cache, $cache_update_needed;
  11.  
  12. if ($type == 'class' && class_exists($name) || $type == 'interface' && interface_exists($name)) {
  13. return TRUE;
  14. }
  15.  
  16. if (!isset($lookup_cache)) {
  17. $lookup_cache = array();
  18. if ($cache = cache_get('lookup_cache', 'cache_bootstrap')) {
  19. $lookup_cache = $cache->data;
  20. }
  21. }
  22.  
  23. // When we rebuild the registry, we need to reset this cache so
  24. // we don't keep lookups for resources that changed during the rebuild.
  25. if ($type == REGISTRY_RESET_LOOKUP_CACHE) {
  26. $cache_update_needed = TRUE;
  27. $lookup_cache = NULL;
  28. return;
  29. }
  30.  
  31. // Called from drupal_page_footer, we write to permanent storage if there
  32. // changes to the lookup cache for this request.
  33. if ($type == REGISTRY_WRITE_LOOKUP_CACHE) {
  34. if ($cache_update_needed) {
  35. cache_set('lookup_cache', $lookup_cache, 'cache_bootstrap');
  36. }
  37. return;
  38. }
  39.  
  40. // $type is either 'interface' or 'class', so we only need the first letter to
  41. // keep the cache key unique.
  42. $cache_key = $type[0] . $name;
  43. if (isset($lookup_cache[$cache_key])) {
  44. if ($lookup_cache[$cache_key]) {
  45. require_once DRUPAL_ROOT . '/' . $lookup_cache[$cache_key];
  46. }
  47. return (bool) $lookup_cache[$cache_key];
  48. }
  49.  
  50. // This function may get called when the default database is not active, but
  51. // there is no reason we'd ever want to not use the default database for
  52. // this query.
  53. $file = Database::getConnection('default', 'default')->query("SELECT filename FROM {registry} WHERE name = :name AND type = :type", array(
  54. ':name' => $name,
  55. ':type' => $type,
  56. ))
  57. ->fetchField();
  58.  
  59. // Flag that we've run a lookup query and need to update the cache.
  60. $cache_update_needed = TRUE;
  61.  
  62. // Misses are valuable information worth caching, so cache even if
  63. // $file is FALSE.
  64. $lookup_cache[$cache_key] = $file;
  65.  
  66. if ($file) {
  67. require_once DRUPAL_ROOT . '/' . $file;
  68. return TRUE;
  69. }
  70. else {
  71. return FALSE;
  72. }
  73. }

留意下面这段代码:

  1. $file= Database::getConnection('default','default')->query("SELECT filename FROM {registry} WHERE name = :name AND type = :type",array(
  2. ':name' => $name,
  3. ':type' => $type,
  4. ))->fetchField();

类加载器要自动加载DatabaseLog这个类,需要去哪里找对应的文件?

Drupal采用了注册表的方式解决这个问题,它将所有可用的类和接口以及它们对应的文件保存一个名为registry的数据表中。类加载器依据类名就可以简单地找到对应的文件。

Drupal如何实现类的自动加载?的更多相关文章

  1. Yaf零基础学习总结5-Yaf类的自动加载

    Yaf零基础学习总结5-Yaf类的自动加载 框架的一个重要功能就是类的自动加载了,在第一个demo的时候我们就约定自己的项目的目录结构,框架就基于这个目录结构来自动加载需要的类文件. Yaf在自启动的 ...

  2. thinkphp系列:类的自动加载是如何设计的

    在使用框架开发时,可以发现框架有很多核心类,却很少看到显示的引入某个文件的代码,这是因为框架都采用了类的自动加载机制,即使用到类时,框架会自动找到该类所在文件的位置并引入该文件.为了更容易看出代码思路 ...

  3. final关键字,类的自动加载,命名空间

    final关键字 1.final可以修饰方法和类,但是不能修饰属性: 2.Final修饰的类不能被继承: 3.Fina修饰的方法不能被重写,子类可以对已被final修饰的父类进行访问,但是不能对父类的 ...

  4. PHP面向对象学习-属性 类常量 类的自动加载 构造函数和析构函数 访问控制(可见性)

    在类的成员方法里面,可以用 ->(对象运算符):$this->property(其中 property 是该属性名)这种方式来访问非静态属性.静态属性则是用 ::(双冒号):self::$ ...

  5. PHP面向对象----- 类的自动加载

    1.类的自动加载 spl_autoload_register函数 test.php <?php spl_autoload_register('autoload'); // require_onc ...

  6. 浅析PHP类的自动加载和命名空间

    php是使用require(require_once)和include(include_once)关键字加载类文件.但是在实际的开发工程中我们基本上不会去使用这些关键字去加载类. 因为这样做会使得代码 ...

  7. 再谈 tp的 实例化 类 的自动加载

    表示一个域名下的所有/任何主机 使用 的格式是: [*.] example.com 其中 , example.com叫着 裸域名. (这个example.com/net/org不能被注册, 被保留) ...

  8. php composer 实现类的自动加载

    我们在开发项目中会经常用到第三方的类库插件,但是如果每次需要使用的时候都会在代码的某一处去引入,然后在实例化,这样做感觉很不方便,那么怎么实现自动加载呢,下面简单介绍使用composer实现自动加载: ...

  9. tp5底层源码分析之------tp5.1类的自动加载机制

    tp框架作为国内主流框架,目前已经发布了6.0版本,相当于3.*版本是进行了重构,今天我们从源码的角度来研究下tp5.1自动加载的实现 作为单入口框架,从入口文件看起,入口文件在public/下,那么 ...

随机推荐

  1. Android:Android SDK Manager

    Android SDK Manager 包含:Tools(构建工具.编译工具.平台工具等) .各种版本SDK.Extras(安卓知识库和辅助工具) 每个SDK至少包含:1.SDK Plaform 2. ...

  2. LINUX下的MYSQL默认表名区分大小写

    让MYSQL不区分表名大小写的方法其实很简单: 1.用ROOT登录,修改/etc/my.cnf,该文件的路径也可能是/usr/my.cnf. 2.加入一行:lower_case_table_names ...

  3. 练习用php做表格

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. bootstrap table 服务器端分页例子

    1,前台引入所需的js 可以从官网上下载 function getTab(){ var url = contextPath+'/fundRetreatVoucher/fundBatchRetreatV ...

  5. RTC硬件时钟设置修改【转】

    转自:http://os.chinaunix.net/a2008/0526/981/000000981211.shtml 这两天一直在做i2c设备驱动的理解,所以很少更新文章. 由于对于表计来说,RT ...

  6. 《c程序设计语言》读书笔记--字符串比较

    举例如下: char a[10]; 1.定义的时候直接用字符串赋值 char a[10]="hello"; 注意:不能先定义再给它赋值,如  char a[10];  a[10]= ...

  7. 每天一个小算法(Shell Sort2)

    希尔排序: 伪代码: input: an array a of length n with array elements numbered 0 to n − 1 inc ← round(n/2) wh ...

  8. hdu - 1240 Nightmare && hdu - 1253 胜利大逃亡(bfs)

    http://acm.hdu.edu.cn/showproblem.php?pid=1240 开始没仔细看题,看懂了发现就是一个裸的bfs,注意坐标是三维的,然后每次可以扩展出6个方向. 第一维代表在 ...

  9. Codeforces Round #215 (Div. 1) B

    出来冒个泡 由于数比较大  开了map计数  然后边走边删边加 勉强可过 #include <iostream> #include<cstdio> #include<cs ...

  10. 权限控制框架Shiro简单介绍及配置实例

    Shiro是什么 http://shiro.apache.org/ Apache Shiro是一个非常易用的Java安全框架,它能提供验证.授权.加密和Session控制.Shiro非常轻量级,而且A ...