You are here

5 drupal_static

admin 的头像
Submitted by admin on 星期五, 2015-09-18 05:58

作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com

我们在阅读Drupal核心代码的时候,可以经常碰到这个函数drupal_static,它的作用是,能够将一个变量缓存起来,在同一HTTP请求期间,重复调用这个变量,不会计算第二次。就是说,如果有这么一个变量,它在一个HTTP请求内,可以被调用多次的话,我们可以只计算一次,然后使用drupal_static将它缓存起来。

我想为breadcrumb2_load_by_path函数,使用drupal_static。这是没有使用drupal_static的代码:

function breadcrumb2_load_by_path($path) {

  $breadcrumbs = breadcrumb2_load_multiple(FALSE, array('path' => $path));

  return reset($breadcrumbs);

}

这是使用后的代码:

function breadcrumb2_load_by_path($path) {

  $cache = &drupal_static(__FUNCTION__, array());

  if (!isset($cache[$path])) {

    $breadcrumbs = breadcrumb2_load_multiple(FALSE, array('path' => $path));

    $cache[$path] = reset($breadcrumbs);

    return $cache[$path];

  }

  return $cache[$path];

}

我对这个函数,开始的时候,最不理解的地方就是__FUNCTION__,后来才弄明白,这是一个PHP常量,上面的代码等价于:

$cache = &drupal_static('breadcrumb2_load_by_path', array());

类似的实现,可以参看Profile2模块里面的profile2_load_by_user,它的这个要复杂很多:

function profile2_load_by_user($account, $type_name = NULL) {

  // Use a separate query to determine all profile ids per user and cache them.

  // That way we can look up profiles by id and benefit from the static cache

  // of the entity loader.

  $cache = &drupal_static(__FUNCTION__, array());

  $uid = is_object($account) ? $account->uid : $account;

 

  if (!isset($cache[$uid])) {

    if (empty($type_name)) {

      $profiles = profile2_load_multiple(FALSE, array('uid' => $uid));

      // Cache ids for further lookups.

      $cache[$uid] = array();

      foreach ($profiles as $pid => $profile) {

        $cache[$uid][$profile->type] = $pid;

      }

      return $profiles ? array_combine(array_keys($cache[$uid]), $profiles) : array();

    }

    $cache[$uid] = db_select('profile', 'p')

      ->fields('p', array('type', 'pid'))

      ->condition('uid', $uid)

      ->execute()

      ->fetchAllKeyed();

  }

  if (isset($type_name)) {

    return isset($cache[$uid][$type_name]) ? profile2_load($cache[$uid][$type_name]) : FALSE;

  }

  // Return an array containing profiles keyed by profile type.

  return $cache[$uid] ? array_combine(array_keys($cache[$uid]), profile2_load_multiple($cache[$uid])) : $cache[$uid];

}

其实这里的逻辑很简单,检查静态变量里面,是否已经存在,如果存在,直接返回;如果不存在,则重新生成一遍。我们这里向函数传递了参数,如果没有传递参数,代码结构会更加简单:

function mymodule_function() {

  $cache = &drupal_static(__FUNCTION__);

  if (!isset($cache)) {

    // 如果没有设置,就计算一遍,为$cache赋值。

  }

  return $ cache;

}


Drupal版本: