function drupal_static

7.x bootstrap.inc &drupal_static($name, $default_value = NULL, $reset = FALSE)

Provides central static variable storage.

All functions requiring a static variable to persist or cache data within a single page request are encouraged to use this function unless it is absolutely certain that the static variable will not need to be reset during the page request. By centralizing static variable storage through this function, other functions can rely on a consistent API for resetting any other function's static variables.

Example:

function language_list($field = 'language') {
  $languages = &drupal_static(__FUNCTION__);
  if (!isset($languages)) {
    // If this function is being called for the first time after a reset,
    // query the database and execute any other code needed to retrieve
    // information about the supported languages.
    ...
  }
  if (!isset($languages[$field])) {
    // If this function is being called for the first time for a particular
    // index field, then execute code needed to index the information already
    // available in $languages by the desired field.
    ...
  }
  // Subsequent invocations of this function for a particular index field
  // skip the above two code blocks and quickly return the already indexed
  // information.
  return $languages[$field];
}
function locale_translate_overview_screen() {
  // When building the content for the translations overview page, make
  // sure to get completely fresh information about the supported languages.
  drupal_static_reset('language_list');
  ...
}

In a few cases, a function can have certainty that there is no legitimate use-case for resetting that function's static variable. This is rare, because when writing a function, it's hard to forecast all the situations in which it will be used. A guideline is that if a function's static variable does not depend on any information outside of the function that might change during a single page request, then it's ok to use the "static" keyword instead of the drupal_static() function.

Example:

function actions_do(...) {
  // $stack tracks the number of recursive calls.
  static $stack;
  $stack++;
  if ($stack > variable_get('actions_max_stack', 35)) {
    ...
    return;
  }
  ...
  $stack--;
}

In a few cases, a function needs a resettable static variable, but the function is called many times (100+) during a single page request, so every microsecond of execution time that can be removed from the function counts. These functions can use a more cumbersome, but faster variant of calling drupal_static(). It works by storing the reference returned by drupal_static() in the calling function's own static variable, thereby removing the need to call drupal_static() for each iteration of the function. Conceptually, it replaces:

$foo = &drupal_static(__FUNCTION__);

with:

// Unfortunately, this does not work.
static $foo = &drupal_static(__FUNCTION__);

However, the above line of code does not work, because PHP only allows static variables to be initializied by literal values, and does not allow static variables to be assigned to references.

The example below shows the syntax needed to work around both limitations. For benchmarks and more information, see http://drupal.org/node/619666.

Example:

function user_access($string, $account = NULL) {
  // Use the advanced drupal_static() pattern, since this is called very often.
  static $drupal_static_fast;
  if (!isset($drupal_static_fast)) {
    $drupal_static_fast['perm'] = &drupal_static(__FUNCTION__);
  }
  $perm = &$drupal_static_fast['perm'];
  ...
}

Parameters

$name: Globally unique name for the variable. For a function with only one static, variable, the function name (e.g. via the PHP magic __FUNCTION__ constant) is recommended. For a function with multiple static variables add a distinguishing suffix to the function name for each one.

$default_value: Optional default value.

$reset: TRUE to reset a specific named variable, or all variables if $name is NULL. Resetting every variable should only be used, for example, for running unit tests with a clean environment. Should be used only though via function drupal_static_reset() and the return value should not be used in this case.

Return value

Returns a variable by reference.

See also

drupal_static_reset()

179 calls to drupal_static()
actions_list in drupal-7.x/includes/actions.inc
Discovers all available actions by invoking hook_action_info().
actions_loop_test_log in drupal-7.x/modules/simpletest/tests/actions_loop_test.module
Write a message to the log.
aggregator_category_load in drupal-7.x/modules/aggregator/aggregator.module
Loads an aggregator category.
aggregator_feed_load in drupal-7.x/modules/aggregator/aggregator.module
Loads an aggregator feed.
archiver_get_info in drupal-7.x/includes/common.inc
Retrieves a list of all available archivers.

... See full list

File

drupal-7.x/includes/bootstrap.inc, line 3335
Functions that need to be loaded on every Drupal request.

Code

function &drupal_static($name, $default_value = NULL, $reset = FALSE) {
  static $data = array(), $default = array();
  // First check if dealing with a previously defined static variable.
  if (isset($data[$name]) || array_key_exists($name, $data)) {
    // Non-NULL $name and both $data[$name] and $default[$name] statics exist.
    if ($reset) {
      // Reset pre-existing static variable to its default value.
      $data[$name] = $default[$name];
    }
    return $data[$name];
  }
  // Neither $data[$name] nor $default[$name] static variables exist.
  if (isset($name)) {
    if ($reset) {
      // Reset was called before a default is set and yet a variable must be
      // returned.
      return $data;
    }
    // First call with new non-NULL $name. Initialize a new static variable.
    $default[$name] = $data[$name] = $default_value;
    return $data[$name];
  }
  // Reset all: ($name == NULL). This needs to be done one at a time so that
  // references returned by earlier invocations of drupal_static() also get
  // reset.
  foreach ($default as $name => $value) {
    $data[$name] = $value;
  }
  // As the function returns a reference, the return should always be a
  // variable.
  return $data;
}