Change record status: 
Project: 
Introduced in branch: 
8.x
Description: 

The serialized data column in the {users} table has been replaced with a service accessible at Drupal::service('user.data').

API

Instead of putting arbitrary data into a single array, the new API stores data separately and requires an explicit module name for each element. Due to that, it is no longer necessary to serialize and unserialize the user data on every user load and save. User data can now be accessed without loading the user entity.

The API is defined by the interface Drupal\user\UserDataInterface, which defines the following methods:

  • get($module, $uid = NULL, $name = NULL)
  • set($module, $uid, $name, $value
  • delete($module = NULL, $uid = NULL, $name = NULL)

The default implementation is Drupal\user\UserData and uses the {user_data} table to store the data. Most arguments for get() and delete() are optional, which makes it possible to load/delete all data of a module/user at once.
The corresponding data is automatically deleted by user.module when either a user is deleted or a module is uninstalled.

Drupal 7

// Get a value.
$data = isset($account->data['mymodule_key']) ? $account->data['mymodule_key'] : 1;

// Add a value.
$account->data['mymodule_key'] = 1;

// Remove a value.
unset($account->data['mymodule_key'])

Drupal 8

// Get a value.
$data = Drupal::service('user.data')->get('mymodule', $account->id(), 'key') ?: 1;

// Set a value.
Drupal::service('user.data')->set('mymodule', $account->id(), 'key', 1);

// Delete a value.
Drupal::service('user.data')->delete('mymodule', $account->id(), 'key');


// Furthermore, new user data management possibilities:

// Get all of a module's key/value pairs for a user account.
$data = Drupal::service('user.data')->get('mymodule', $account->id());

// Get all stored values for a module's key.
$data = Drupal::service('user.data')->get('mymodule', NULL, 'key');

// Get all stored values for a module.
// Note: Only use this if you are sure that there is data for a
// small amount of user accounts only!
$data = Drupal::service('user.data')->get('mymodule');

Upgrade path

During the core upgrade from 7.x to 8.x, all data in {users}.data is moved to a helper table called {_d7_user_data}, a row for each top-level array key and user. That allows build a SELECT ... FROM ... query that can take data over to the default user_data table and then delete it as in the following example from contact.module:

  $query = db_select('_d7_users_data', 'ud');
  $query->condition('name', 'contact');
  $query->addField('ud', 'uid');
  $query->addExpression("'contact'", 'module');
  $query->addExpression("'enabled'", 'name');
  $query->addField('ud', 'value', 'value');
  $query->addExpression(1, 'serialized');

  db_insert('users_data')
    ->from($query)
    ->execute();
  db_delete('_d7_users_data')
    ->condition('name', 'contact')
    ->execute();
Impacts: 
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done