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. JavaScript事件冒泡和事件委托

    JavaScript事件冒泡和事件委托 付建宇 - 2 条评论 接触JavaScript不久,学的东西也不是特别多.小雨就是习惯把平时学到的东西拿出来分享.一方面加强自己的印象,一方面可以让自己的经验 ...

  2. JLINK固件,JLINK驱动和JLINK硬件版本之间的关系,以及固件升级方法

    初学者容易在这几个问题上面犯迷糊,这里简单的说说.   1. JLINK硬件版本首先说JLINK的硬件版本有V7,V8和V9,相信这一点大家应该都没问题,那怎么看自己手头的JLINK是哪个硬件版本呢, ...

  3. centos增加网卡

    我做了一個傻事,要在Server上新增一張網卡,可是因為一直無法啟動, 所以很自然的以為CentOS 6又多了其他的設定要求, 因此查了兩天的資料,也試過很多方式,但都沒有效用. 今天早上心血來潮,想 ...

  4. iOS:核心动画的详解介绍:CAAnimation(抽象类)及其子类

    核心动画的详解介绍:CAAnimation(抽象类)   1.核心动画基本概念 Core Animation是一组非常强大的动画处理API,使用它能做出非常炫丽的动画效果,而且往往是事半功倍! 使用它 ...

  5. 关于请求添加HttpRequestHeader

    WebClient w = new WebClient(); w.Headers.Add(HttpRequestHeader.Accept, "application/json") ...

  6. flex Bindable

    [Bindable]大概又是Flex用得最多的元数据了.刚开始用用确实好简单,效率真是没的说.不过这几天用着却碰到了些问题,我自己搜集了些资料,想着有必要在blog里总结一下吧. 啥是元数据(meta ...

  7. BZOJ 2006 超级钢琴(划分树+优先队列)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2006 题意: 给出一个数列A,L,R,构造出一个新的集合,集合中的数字为A中任意连续t( ...

  8. 1427. SMS(DP)

    1427 题意不太好理解 其它没什么 细心啊 细心 一个0写成了1 WA半天 以每个字符是以第一种方式还是第二种方式来D #include <iostream> #include<c ...

  9. R语言AMORE包实现BP神经网络——German数据集

    library(AMORE)data<-read.table('G:\\dataguru\\ML\\ML09\\基于BP网络的个人信贷信用评估\\基于BP网络的个人信贷信用评估\\german. ...

  10. openerp 7 在ubuntu上设置开机启动

    我们要让openerp开机运行起来. 第一步,先进入系统目录: cd /etc/init.d 第二步,创建文件.命名为openerp-server sudo vi openepr-server 第三步 ...