• Drupal如何实现类的自动加载?


    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的数据表中。类加载器依据类名就可以简单地找到对应的文件。

  • 相关阅读:
    Python——装饰器
    黑马Python——学习之前
    遇到的问题及解决办法——待完善
    springboot @Slf4j log 日志配置 控制台输出彩色日志并过滤DEBUG日志
    常用linux指令
    Spring Security内置 Filter 全解析
    jquery attr与prop区别。
    instanceof不能跨框架判定数组类型,必须用Array.isArray方法,实例
    font-size:em单位
    通过简单的css样式让按钮居中显示
  • 原文地址:https://www.cnblogs.com/eastson/p/3352170.html
Copyright © 2020-2023  润新知