logo

Types de blocs supplémentaires (EBT) – Nouvelle expérience de Layout Builder❗

Types de blocs supplémentaires (EBT) – types de blocs stylisés et personnalisables : diaporamas, onglets, cartes, accordéons et bien d’autres. Paramètres intégrés pour l’arrière-plan, la boîte DOM, les plugins JavaScript. Découvrez dès aujourd’hui le futur de la création de mises en page.

Démo des modules EBT Télécharger les modules EBT

❗Types de paragraphes supplémentaires (EPT) – Nouvelle expérience Paragraphes

Types de paragraphes supplémentaires (EPT) – ensemble de modules basé sur les paragraphes analogiques.

Démo des modules EPT Télécharger les modules EPT

Défilement
05/07/2025, by Ivan

Les requêtes d'insertion doivent toujours utiliser un objet constructeur de requêtes. Dans certaines bases de données, un traitement spécial des champs LOB (Large OBject, par exemple TEXT dans MySQL) et BLOB (Binary Large OBject) est nécessaire, ce qui demande un niveau d'abstraction pour que les différents pilotes de bases de données puissent implémenter le traitement spécifique requis.

Les requêtes d'insertion sont lancées en utilisant la méthode insert() de la manière suivante :

$query = $connection->insert('mytable', $options);

Cela crée un objet de requête d'insertion qui insérera une ou plusieurs entrées dans la table mytable. Notez que les accolades ne sont pas nécessaires autour du nom de la table, car le constructeur de requêtes s'en charge automatiquement.

L'objet de requête d'insertion utilise une API fluide. C'est-à-dire que toutes les méthodes (sauf execute()) retournent l'objet de requête lui-même, permettant de chaîner les appels de méthodes. Dans de nombreux cas, cela signifie que l'objet de requête n'a même pas besoin d'être stocké dans une variable.

L'objet de requête d'insertion supporte plusieurs modèles d'utilisation pour répondre à divers besoins. En général, le flux de travail consiste à indiquer les champs dans lesquels la requête insérera des données, à définir les valeurs à insérer dans ces champs, puis à exécuter la requête. Les modèles d'utilisation les plus courants sont listés ci-dessous.

Forme compacte

La forme préférée pour la plupart des requêtes d'insertion est la forme compacte :

$result = $connection->insert('mytable')
  ->fields([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])
  ->execute();

Cela équivaut à la requête suivante :

INSERT INTO {mytable} (title, uid, created) VALUES ('Example', 1, 1221717405);

Le fragment ci-dessus combine les parties clés du processus d'insertion.

$connection->insert('mytable')

Cette ligne crée un nouvel objet de requête d'insertion pour la table mytable.

  ->fields([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])

La méthode fields() accepte plusieurs formes de paramètres, mais l'utilisation la plus courante est un tableau associatif. Les clés du tableau sont les colonnes de la table dans lesquelles insérer, et les valeurs sont les valeurs correspondantes à insérer. Cela aboutira à une seule requête d'insertion dans la table spécifiée.

  ->execute();

La méthode execute() demande l'exécution de la requête. Si cette méthode n'est pas appelée, la requête ne sera pas exécutée.

Contrairement aux autres méthodes de l'objet requête Insert, qui retournent l'objet lui-même, execute() retourne la valeur du champ auto-incrémenté (type séquentiel dans hook_schema()) qui a été insérée par la requête, si un tel champ existe. C'est pourquoi la valeur retournée lui est assignée à $result dans l'exemple ci-dessus. Si aucun champ auto-incrémenté n'existe, la valeur retournée par execute() n'est pas définie et ne doit pas être utilisée.

Dans un cas typique, c'est le format préféré pour les requêtes d'insertion.

Forme dégradée

$result = $connection->insert('mytable')
  ->fields(['title', 'uid', 'created'])
  ->values([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])
  ->execute();

Ceci est une version un peu plus détaillée de la requête précédente et aura exactement le même résultat.

  ->fields(['title', 'uid', 'created'])

Lorsque fields() est appelé avec un tableau indexé plutôt qu'un tableau associatif, il définit uniquement les champs (colonnes de la base de données) qui seront utilisés dans la requête, sans définir de valeurs pour ceux-ci. Cela est utile pour préparer une requête multi-page qui sera exécutée plus tard.

  ->values([
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ])

Cette méthode définit un tableau associatif des noms des champs avec les valeurs à insérer dans ces champs. La méthode values() peut aussi accepter un tableau indexé. Si un tableau indexé est utilisé, l'ordre des valeurs doit correspondre à celui des champs définis dans fields(). Si un tableau associatif est utilisé, l'ordre peut être quelconque. En général, le tableau associatif est préféré pour la lisibilité.

Cette forme de requête est rarement utilisée, car la forme compacte est préférée. Dans la plupart des cas, la seule raison de séparer fields() et values() est d'exécuter une requête multi-page.

Forme avec plusieurs insertions

L'objet de requête Insert peut aussi accepter plusieurs ensembles de valeurs. Autrement dit, values() peut être appelé plusieurs fois pour mettre en file d'attente plusieurs instructions d'insertion. La manière dont cela sera traité dépendra des capacités de la base de données utilisée. Dans la plupart des bases de données, plusieurs insertions seront exécutées ensemble dans une transaction pour garantir l'intégrité des données et améliorer la vitesse. Dans MySQL, il utilisera la syntaxe d'insertion multiple propre à MySQL.

$values = [
  [
    'title' => 'Example',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ],
  [
    'title' => 'Example 2',
    'uid' => 1,
    'created' => \Drupal::time()->getRequestTime(),
  ],
  [
    'title' => 'Example 3',
    'uid' => 2,
    'created' => \Drupal::time()->getRequestTime(),
  ],
];
$query = $connection->insert('mytable')->fields(['title', 'uid', 'created']);
foreach ($values as $record) {
  $query->values($record);
}
$query->execute();

Dans l'exemple ci-dessus, trois instructions d'insertion seront exécutées ensemble comme une seule unité, utilisant la méthode la plus efficace pour le pilote de base de données utilisé. Notez que nous avons stocké l'objet de requête dans une variable pour pouvoir itérer sur $values et appeler plusieurs fois la méthode values().

Dans la forme dégradée, l'exemple ci-dessus est équivalent aux trois requêtes suivantes :

INSERT INTO {mytable} (title, uid, created) VALUES ('Example', 1, 1221717405);
INSERT INTO {mytable} (title, uid, created) VALUES ('Example 2', 1, 1221717405);
INSERT INTO {mytable} (title, uid, created) VALUES ('Example 3', 2, 1221717405);

Notez que dans le cas d'insertion multiple, la valeur retournée par execute() n'est pas définie et ne doit pas être considérée comme fiable, car elle peut varier selon le pilote de base de données.

Insertion à partir d'une requête select

Si vous souhaitez remplir une table avec les résultats provenant d'autres tables, vous devez soit sélectionner via SELECT les tables sources, parcourir les données en PHP, puis les insérer dans la nouvelle table, soit exécuter une requête INSERT INTO ... SELECT FROM dans laquelle chaque enregistrement retourné par la requête SELECT est inséré par la requête INSERT.

Dans cet exemple, nous souhaitons construire la table mytable contenant le nid et le nom d'utilisateur pour tous les nœuds dans le système qui ont le type page.

<?php
// Construire la requête SELECT.
$query = $connection->select('node', 'n');
// Faire une jointure avec la table users.
$query->join('users', 'u', 'n.uid = u.uid');
// Ajouter les champs désirés.
$query->addField('n', 'nid');
$query->addField('u', 'name');
// Ajouter une condition pour ne récupérer que les nœuds de type page.
$query->condition('type', 'page');

// Exécuter l'insertion.
$connection->insert('mytable')
  ->from($query)
  ->execute();
?>

Valeurs par défaut

Normalement, si vous ne spécifiez pas de valeur pour un champ donné et qu'une valeur par défaut est définie dans le schéma de la table, la base de données insérera automatiquement cette valeur par défaut pour vous. Cependant, dans certains cas, vous devez explicitement indiquer à la base de données d'utiliser la valeur par défaut. Cela inclut si vous souhaitez utiliser toutes les valeurs par défaut pour l'ensemble de l'enregistrement. Pour indiquer explicitement à la base de données d'utiliser la valeur par défaut pour un champ donné, la méthode useDefaults() existe.

$query->useDefaults(['field1', 'field2']);

Cette ligne indique à la requête d'utiliser les valeurs par défaut spécifiées pour les champs field1 et field2. Notez que spécifier un même champ dans useDefaults() et dans fields() ou values() provoque une erreur et une exception sera levée.

$connection->insert() ou $connection->query()

Il s'agit d'une question fréquemment posée. (Voir les commentaires sur cette page.) Quelle est la différence entre insert() et query() ?

Dans insert(), chaque colonne est spécifiée comme une entrée distincte dans le tableau de champs, et le code peut nettoyer la valeur de chaque colonne. query() utilise une chaîne SQL sans possibilité de vérifier chaque colonne individuellement. Si vous utilisez query() avec des placeholders, le code peut valider les valeurs des colonnes, mais les placeholders sont optionnels, et il n'y a aucun moyen de garantir que votre SQL ne contient pas de valeurs non échappées.

insert() fait passer la requête par une série de hooks, permettant aux autres modules de vérifier et modifier vos requêtes. C'est la bonne manière d'interagir avec d'autres modules. query() est un peu plus rapide parce qu'il ne passe pas par ces hooks. Vous pouvez gagner du temps de traitement, mais votre code ne permettra pas aux autres modules d'intervenir.

insert() est plus compatible avec d'autres bases de données et avec les futures versions de Drupal.