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

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

你可能感兴趣的:(drupal)