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

function _drupal_bootstrap_database() {
// ... ....
spl_autoload_register('drupal_autoload_class');
spl_autoload_register('drupal_autoload_interface');
}

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

function drupal_autoload_interface($interface) {
return _registry_check_code('interface', $interface);
} function drupal_autoload_class($class) {
return _registry_check_code('class', $class);
} function _registry_check_code($type, $name = NULL) {
static $lookup_cache, $cache_update_needed; if ($type == 'class' && class_exists($name) || $type == 'interface' && interface_exists($name)) {
return TRUE;
} if (!isset($lookup_cache)) {
$lookup_cache = array();
if ($cache = cache_get('lookup_cache', 'cache_bootstrap')) {
$lookup_cache = $cache->data;
}
} // When we rebuild the registry, we need to reset this cache so
// we don't keep lookups for resources that changed during the rebuild.
if ($type == REGISTRY_RESET_LOOKUP_CACHE) {
$cache_update_needed = TRUE;
$lookup_cache = NULL;
return;
} // Called from drupal_page_footer, we write to permanent storage if there
// changes to the lookup cache for this request.
if ($type == REGISTRY_WRITE_LOOKUP_CACHE) {
if ($cache_update_needed) {
cache_set('lookup_cache', $lookup_cache, 'cache_bootstrap');
}
return;
} // $type is either 'interface' or 'class', so we only need the first letter to
// keep the cache key unique.
$cache_key = $type[0] . $name;
if (isset($lookup_cache[$cache_key])) {
if ($lookup_cache[$cache_key]) {
require_once DRUPAL_ROOT . '/' . $lookup_cache[$cache_key];
}
return (bool) $lookup_cache[$cache_key];
} // This function may get called when the default database is not active, but
// there is no reason we'd ever want to not use the default database for
// this query.
$file = Database::getConnection('default', 'default')->query("SELECT filename FROM {registry} WHERE name = :name AND type = :type", array(
':name' => $name,
':type' => $type,
))
->fetchField(); // Flag that we've run a lookup query and need to update the cache.
$cache_update_needed = TRUE; // Misses are valuable information worth caching, so cache even if
// $file is FALSE.
$lookup_cache[$cache_key] = $file; if ($file) {
require_once DRUPAL_ROOT . '/' . $file;
return TRUE;
}
else {
return FALSE;
}
}

留意下面这段代码:

$file= Database::getConnection('default','default')->query("SELECT filename FROM {registry} WHERE name = :name AND type = :type",array(
':name' => $name,
':type' => $type,
))->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. mysql和oracle的一个汉字占几个字符

    以前一直使用oracle11g,一个汉字占3个字节,所以在操作mysql时也一直这样分配长度. 今天测试了下发现不对了 可以看到第一个的长度确实是15,但是第二个为什么是5? 在网上找到资料:char ...

  2. Spring Security资料

    Spring Security学习总结一 Spring Security3.1登陆验证 Spring security初探

  3. 人脸识别算法准确率最终超过了人类 The Face Recognition Algorithm That Finally Outperforms Humans

    Everybody has had the experience of not recognising someone they know—changes in pose, illumination ...

  4. 《Java编程那点事儿》读书笔记(一)——基本数据结构

    觉得自己记忆力很烂的样子,读书不做笔记就好像没读一样,所以决定以后读技术类的书籍,都要做好笔记. 1.IP地址和域名:如果把IP地址类比成身份证号的话,域名就是持证人的名字. 2.端口:规定一个 设备 ...

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

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

  6. JS方法

    1.方法可作为对象使用 function aa() { this.a = "aaaa"; this.b = 23; this.f = function () { alert(thi ...

  7. J2EE如何生成验证码图片和点击刷新验证码

    验证码图片生成步骤 创建BufferedImage对象. 获取BufferedImage的画笔,即调用getGraphics()方法获取Graphics对象. 调用Graphics对象的setColo ...

  8. AOJ - 0009 Prime Number (素数筛法) && AOJ - 0005 (求最大公约数和最小公倍数)

    http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34870 求n内的素数个数. /* ********************* ...

  9. jsp之jstl标签

    常用jstl标签 一.<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> ...

  10. Android中使用ListView实现分页刷新(线程休眠模拟)(滑动加载列表)

    当要显示的数据过多时,为了更好的提升用户感知,在很多APP中都会使用分页刷新显示,比如浏览新闻,向下滑动到当前ListView的最后一条信息(item)时,会提示刷新加载,然后加载更新后的内容.此过程 ...