You are here

function drupal_static in Zircon Profile 8.0

Same name and namespace in other branches
  1. 8 core/includes/bootstrap.inc \drupal_static()

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 mymodule_log_stream_handle($new_handle = NULL) {
  static $handle;
  if (isset($new_handle)) {
    $handle = $new_handle;
  }
  return $handle;
}

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 initialized 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 https://www.drupal.org/node/619666.

Example:


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

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 one or all variables(s). This parameter is only used internally and should not be passed in; use drupal_static_reset() instead. (This function's return value should not be used when TRUE is passed in.)

Return value

Returns a variable by reference.

See also

drupal_static_reset()

47 calls to drupal_static()
BookManager::bookSubtreeData in core/modules/book/src/BookManager.php
Gets the data representing a subtree of the book hierarchy.
BookManager::bookTreeAllData in core/modules/book/src/BookManager.php
Gets the data structure representing a named menu tree.
BookManager::doBookTreeBuild in core/modules/book/src/BookManager.php
Builds a book tree.
comment_node_update_index in core/modules/comment/comment.module
Implements hook_node_update_index().
drupal_attach_tabledrag in core/includes/common.inc
Assists in attaching the tableDrag JavaScript behavior to a themed table.

... See full list

File

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