Alternate way of storing variables in Drupal

Many times when coding a custom module, there is a need to store a number of variables. I've seen many developers use the variables table using variable_get(), variable_set(), and variable_del(). The problem with doing that is all of those variable get loaded on every single page load. On large sites with many modules, the variables table can get quite large and can require a lot of memory. Here is a quick example module you can use which uses a separate table for variable storage and an easy way to get, set, and delete variables. After a variable is requested, it is cached for the remainder of the request so that there is no performance penalty for requesting the varible many times in one request.

The module includes 4 files:
alt_variables/AltVar.php - A class which contains the main logic.
alt_variables/alt_variables.info - Standard module information file
alt_variables/alt_variables.install - Contains the database schema information which creates the db table on installation and deletes it on uninstallation.
alt_variables/alt_variables.module - Doesn't contain any code but Drupal requires it to be present.

<?php
 
/**
 * @file AltVar.php
 * 
 * Gets, sets, and deletes variables.
 */
 
/**
 * Gets, sets, and deletes variables.
 */
class AltVar {
 
  /**
   * Gets, sets, and deletes variables. Uses drupal_static();
   * 
   * Usage:
    <pre>
    AltVar::set('test', 'value');
    AltVar::get('test');
    AltVar::del('test');
    </pre>
   */
  public function __construct() {
 
  }
 
  /**
   * Gets a variable from the alt_variables table.
   */
  public function get($id = NULL, $default = NULL) {
    if (is_null($id)) {
      return NULL;
    }
 
    $value = &drupal_static($id);
    if (!isset($value)) {
      $value = self::dbGet($id);
      if ($value) {
        $value = unserialize($value);
      }
    }
    if (!$value) {
      $value = NULL;
    }
    return !is_null($value) ? $value : $default;
  }
 
  /**
   * Sets a value in the alt_variables table.
   */
  public function set($id = NULL, $value = NULL) {
    if (is_null($id) || is_null($value)) {
      return FALSE;
    }
    $cache = &drupal_static($id);
    $cache = $value;
    self::dbSet(array('id' => $id, 'value' => serialize($value)));
 
    return TRUE;
  }
 
  /**
   * Deletes a value from the alt_variables table.
   * 
   * @return boolean 1 on success or 0 on failure.
   */
  public function del($id = NULL) {
    if (is_null($id)) {
      return 0;
    }
    return self::dbDel($id);
  }
 
  /**
   * Gets a value from the alt_variables table.
   */
  protected function dbGet($id) {
    $query = db_select('alt_variables', 'av')
        ->fields('av', array('value'))
        ->condition('id', $id)
        ->execute()
        ->fetchAll();
    return array_key_exists(0, $query) && isset($query[0]->value) ? $query[0]->value : NULL;
  }
 
  /**
   * Inserts a value into the alt_variables table.
   * 
   * @param array $entry array('id' => 'my_variable', 'value' => 'my_value');
   */
  protected function dbInsert($entry) {
    $return_value = NULL;
    try {
      $return_value = db_insert('alt_variables')
          ->fields($entry)
          ->execute();
    } catch (Exception $e) {
      drupal_set_message(t('db_insert failed. Message = %message, query= %query', array('%message' => $e->getMessage(), '%query' => $e->query_string)), 'error');
    }
    return $return_value;
  }
 
  /**
   * Updates a value from the alt_variables table.
   */
  protected function dbUpdate($entry) {
    try {
      $count = db_update('alt_variables')
          ->fields($entry)
          ->condition('id', $entry['id'])
          ->execute();
    } catch (Exception $e) {
      drupal_set_message(t('db_update failed. Message = %message, query= %query', array('%message' => $e->getMessage(), '%query' => $e->query_string)), 'error');
    }
    return $count;
  }
 
  /**
   * Updates or inserts a value from the alt_variables table depending on whether
   * it exists or not
   */
  protected function dbSet($entry) {
    $isset = self::get($entry['id']);
    if ($isset) {
      self::dbUpdate($entry);
    } else {
      self::dbInsert($entry);
    }
  }
 
  /**
   * Deletes a value from the alt_variables table
   * 
   * @return int number of records deleted
   */
  protected function dbDel($id) {
    $num_deleted = db_delete('alt_variables')
        ->condition('id', $id)
        ->execute();
    return $num_deleted;
  }
 
}
?>

alt_variables.info:

name = Alternate Variables
description = An alternate way to store misc variables
core = 7.x
version = 7.x-1.0
files[] = AltVar.php
<?php
/**
 * @file
 * alt_variables.install 
 */
 
/**
 * Implements hook_schema().
 */
function alt_variables_schema() {
 
  $schema['alt_variables'] = array(
    'description' => 'Stores generic data.',
    'fields' => array(
      'id'  => array(
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
        'description' => 'Key of generic data.',
      ),
      'value' => array(
        'type' => 'blob',
        'not null' => TRUE,
        'size' => 'big',
        'translatable' => TRUE,
        'description' => "Value of generic data",
      ),
    ),
    'primary key' => array('id'),
  );
 
  return $schema;
}
?>
<?php
 
/**
 * @file
 * THIS FILE INTENTIONALLY LEFT BLANK.
 *
 * alt_variables.module
 * 
 * Yes, there is no code in the .module file. Alt Variable operates entirely
 * through the AltVar class.
 */

Tags

Internal References

Article Type

General