All of the db_* procedural functions part of the Database API layer have been deprecated.
The recommended way to call database API functions is now to obtain the database connection object and execute operations on it.
In most of the cases (that is when the code is executing on a fully bootstrapped Drupal where the container is available), the database connection should be injected as a service through the constructor like for example:
...
use Drupal\Core\Database\Connection;
...
class MyController {
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $connection;
/**
* Constructs this factory object.
*
* @param \Drupal\Core\Database\Connection $connection
* The Connection object.
*/
public function __construct(Connection $connection) {
$this->connection = $connection;
}
...
public function myMethod() {
return $this->connection->nextId();
}
...
}
where it is not possible to inject the service, the \Drupal::database()
helper can be used, for example:
...
public function myProceduralFunction() {
$connection = \Drupal::database();
return $connection->nextId();
}
...
If code needs to access database in contexts where the container is not yet available, call the static getConnection()
method from the Database
class, for example:
...
use Drupal\Core\Database\Database;
...
class MyController {
...
public function myMethod() {
$connection = Database::getConnection();
return $connection->nextId();
}
...
}
The recommended way to access to database API in PHPUnit tests is still under discussion at #2991337: Document the recommended ways to obtain the database connection object.
See below the table of the deprecated functions with their new alternatives.
Deprecated function | New method |
---|---|
db_add_field | $injected_database->schema()->addField($table, $field, $spec, $keys_new) |
db_add_index | $injected_database->schema()->addIndex($table, $name, $fields, $spec) |
db_add_primary_key | $injected_database->schema()->addPrimaryKey($table, $fields) |
db_add_unique_key | $injected_database->schema()->addUniqueKey($table, $name, $fields) |
db_and | Create a \Drupal\Core\Database\Query\Condition object, specifying an AND conjunction: new Condition('AND'); |
db_change_field | $injected_database->schema()->changeField($table, $field, $field_new, $spec, $keys_new) |
db_close | \Drupal\Core\Database\Database::closeConnection($target) |
db_condition | Create a \Drupal\Core\Database\Query\Condition object, specifying the desired conjunction: new Condition($conjunction); |
db_create_table | $injected_database->schema()->createTable($name, $table) |
db_delete | $injected_database->delete($table, $options) |
db_driver | $injected_database->driver() |
db_drop_field | $injected_database->schema()->dropField($table, $field) |
db_drop_index | $injected_database->schema()->dropIndex($table, $name) |
db_drop_primary_key | $injected_database->schema()->dropPrimaryKey($table) |
db_drop_table | $injected_database->schema()->dropTable($table) |
db_drop_unique_key | $injected_database->schema()->dropUniqueKey($table, $name) |
db_escape_field | $injected_database->escapeField($field) |
db_escape_table | $injected_database->escapeTable($table) |
db_field_exists | $injected_database->schema()->fieldExists($table, $field) |
db_field_names | $injected_database->schema()->fieldNames($fields) |
db_field_set_default | use $injected_database->schema()->changeField($table, $field, $field_new, $spec, $keys_new) passing a full field specification |
db_field_set_no_default | use $injected_database->schema()->changeField($table, $field, $field_new, $spec, $keys_new) passing a full field specification |
db_find_tables | $injected_database->schema()->findTables($table_expression) |
db_index_exists | $injected_database->schema()->indexExists($table, $name) |
db_insert | $injected_database->insert($table, $options) |
db_like | $injected_database->escapeLike($string) |
db_merge | $injected_database->merge($table, $options) |
db_next_id | $injected_database->nextId($existing_id) |
db_or | Create a \Drupal\Core\Database\Query\Condition object, specifying an OR conjunction: new Condition('OR'); |
db_query | $injected_database->query($query, $args, $options) |
db_query_range | $injected_database->queryRange($query, $from, $count, $args, $options) |
db_query_temporary | $injected_database->queryTemporary($query, $args, $options) |
db_rename_table | $injected_database->schema()->renameTable($table, $new_name) |
db_select | $injected_database->select($table, $alias, $options) |
db_set_active | \Drupal\Core\Database\Database::setActiveConnection($key) |
db_table_exists | $injected_database->schema()->tableExists($table) |
db_transaction | $injected_database->startTransaction($name) |
db_truncate | $injected_database->truncate($table, $options) |
db_update | $injected_database->update($table, $options) |
db_xor | Create a \Drupal\Core\Database\Query\Condition object, specifying an XOR conjunction: new Condition('XOR'); |
'target' entry in the $options array for DB API methods is no longer supported.
Also note that passing ['target' => 'replica']
entries to the options array in calls to DB API methods is no longer supported. Instead, the required replica connection needs to be identified beforehand using the database.replica
service, and the operation executed on it.
Before:
...
$query = db_select('search_index', 'i', ['target' => 'replica']);
...
After:
...
$database_replica = \Drupal::service('database.replica');
$query = $database_replica->select('search_index', 'i'):
...
Comments
Documentation
For example for selects: https://www.drupal.org/docs/drupal-apis/database-api/static-queries
For example for updates: https://www.drupal.org/docs/drupal-apis/database-api/update-queries
benjamin, Agaric