function drupal_static

8.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 example_list($field = 'default') {
  $examples = &drupal_static(__FUNCTION__);
  if (!isset($examples)) {
    // 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.
    ...
  }
  if (!isset($examples[$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 $examples 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 $examples[$field];
}
function examples_admin_overview() {
  // When building the content for the overview page, make sure to get
  // completely fresh information.
  drupal_static_reset('example_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 system_get_module_info($property) {
  static $info;
  if (!isset($info)) {
    $info = new ModuleInfo('system_info', 'cache');
  }
  return $info[$property];
}

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()

127 calls to drupal_static()
aggregator_category_load in drupal/core/modules/aggregator/aggregator.module
Loads an aggregator category.
arg in drupal/core/includes/bootstrap.inc
Returns a component of the current Drupal path.
block_list in drupal/core/modules/block/block.module
Returns all blocks in the specified region for the current user.
book_get_flat_menu in drupal/core/modules/book/book.module
Gets the book menu tree for a page and returns it as a linear array.
book_menu_subtree_data in drupal/core/modules/book/book.module
Gets the data representing a subtree of the book hierarchy.

... See full list

File

drupal/core/includes/bootstrap.inc, line 2956
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;
}