logo

Extra Block Types (EBT) - Nieuwe Layout Builder ervaring❗

Extra Block Types (EBT) - gestileerde, aanpasbare bloktypes: Slideshows, Tabs, Cards, Accordions en vele andere. Ingebouwde instellingen voor achtergrond, DOM Box, javascript-plugins. Ervaar vandaag al de toekomst van layout building.

Demo EBT-modules Download EBT-modules

❗Extra Paragraph Types (EPT) - Nieuwe Paragraphs ervaring

Extra Paragraph Types (EPT) - analoge op paragrafen gebaseerde set modules.

Demo EPT-modules Download EPT-modules

Scroll
03/10/2025, by Ivan

De meest voorkomende SELECT-query’s in Drupal zijn statische query’s met behulp van de methode query() van het databaseconnectie-object.
Statische query’s worden vrijwel letterlijk naar de database doorgestuurd.

Voorbeeld:

$database = \Drupal::database();
$query = $database->query("SELECT id, example FROM {mytable}");
$result = $query->fetchAll();

Alleen zeer eenvoudige SELECT-query’s zouden de statische query()-methode moeten gebruiken. Je moet een dynamische query gebruiken als je meer complexe query’s, dynamische querygeneratie of flexibiliteit nodig hebt.

Gebruik deze functie niet voor eenvoudige INSERT-, UPDATE- of DELETE-query’s. Die moeten worden afgehandeld via respectievelijk insert(), update() en delete(). Voor complexere DELETE-query’s met meerdere tabellen, zie Complexe DELETE-query’s.

Argumenten

De methode query() van het databaseconnectie-object accepteert drie argumenten:

  • $query: de uit te voeren query. Gebruik indien nodig placeholders en zet alle tabelnamen tussen accolades.
  • $args: een array met waarden voor de placeholders die in de query worden vervangen.
  • $options: een array met opties om de uitvoering van de query te controleren (optioneel).

Tabelnaamvoorvoegsel

In statische query’s moeten alle tabelnamen tussen accolades {...} worden gezet.

Het plaatsen van tabelnamen tussen accolades markeert ze zodat het databasesysteem er indien nodig een prefix aan kan toevoegen. Met een prefix kunnen meerdere sites dezelfde database gebruiken of in sommige gevallen geselecteerde tabellen tussen sites delen. Dit voorkomt ook dat gegevens van de hostsite in tests lekken.

Placeholders

Placeholders geven aan waar een waarde in de query moet worden ingevoegd. Door ze te scheiden van de query zelf, kan de database onderscheid maken tussen SQL-syntaxis en door de gebruiker aangeleverde waarden, waardoor SQL-injecties worden voorkomen.

$query = $database->query("SELECT id, example FROM {mytable} WHERE created > :created", [
  ':created' => REQUEST_TIME - 3600,
]);

Bovenstaande code selecteert alle mytable-ID’s en voorbeelden die in het afgelopen uur (3600 seconden) zijn aangemaakt. De placeholder :created wordt dynamisch vervangen door de waarde van REQUEST_TIME - 3600 op het moment dat de query wordt uitgevoerd.

Een query kan meerdere placeholders hebben, maar ze moeten allemaal unieke namen hebben, zelfs als ze dezelfde waarde bevatten. Afhankelijk van de use case kan de array met placeholders inline worden gedefinieerd (zoals hierboven) of vooraf worden opgebouwd en doorgegeven. De volgorde van de array maakt niet uit.

Placeholders die beginnen met "db_" zijn gereserveerd voor intern gebruik door het systeem en mogen nooit expliciet worden opgegeven.

Let op: placeholders mogen niet handmatig ge-escaped of tussen aanhalingstekens worden gezet, ongeacht hun type. Omdat ze afzonderlijk naar de databaseserver worden gestuurd, kan de server zelf onderscheid maken tussen de querystring en de waarde.

// FOUT (aanhalingstekens rond de :type placeholder)
$result = $database->query("SELECT example FROM {mytable} WHERE type = ':type'", [
  ':type' => 'mytype',
]);

// CORRECT (geen aanhalingstekens rond de :type placeholder)
$result = $database->query("SELECT example FROM {mytable} WHERE type = :type", [
  ':type' => 'mytype',
]);

Placeholders kunnen niet worden gebruikt voor kolom- en tabelnamen. Als deze uit onveilige invoer komen, moeten ze door $database->escapeTable() gehaald worden.

Array-placeholders

Het databaselevel van Drupal ondersteunt ook array-placeholders. Als een waarde voor een placeholder een array is, wordt deze automatisch uitgebreid tot een kommagescheiden lijst, net zoals de placeholder. Dit betekent dat ontwikkelaars zich geen zorgen hoeven te maken over het tellen van placeholders.

Voorbeeld:

$result = $database->query("SELECT * FROM {mytable} WHERE id IN (:ids[])", [':ids[]' => [13, 42, 144]]);

De volgende twee statements zijn gelijkwaardig aan het bovenstaande:

$result = $database->query("SELECT * FROM {mytable} WHERE id IN (:ids_1, :ids_2, :ids_3)", [
  ':ids_1' => 13, 
  ':ids_2' => 42, 
  ':ids_3' => 144,
]);

$result = $database->query("SELECT * FROM {mytable} WHERE id IN (13, 42, 144)");

Query-opties

De derde parameter van de query()-methode is een array met opties die het gedrag van de query bepalen. Meestal zijn er slechts twee directieven die in de meeste gevallen worden gebruikt. Andere opties zijn vooral voor intern gebruik.

De sleutel "target" geeft aan welke doelverbinding moet worden gebruikt. Als dit niet wordt opgegeven, wordt standaard "default" gebruikt. Het enige andere geldige doel is "replica", waarmee de query naar een replicaserver wordt gestuurd als die bestaat.

De sleutel "fetch" bepaalt hoe de rijen worden opgehaald die door de query worden geretourneerd. Geldige waarden zijn PDO::FETCH_OBJ, PDO::FETCH_ASSOC, PDO::FETCH_NUM, PDO::FETCH_BOTH of een string die een klassennaam vertegenwoordigt. Als een string wordt opgegeven, wordt elke rij opgehaald als een object van die klasse. Alle andere waarden worden afgehandeld door PDO: als stdClass-object, associatieve array, numerieke array of gemengde array. Zie http://php.net/manual/en/pdostatement.fetch.php. Standaard wordt PDO::FETCH_OBJ gebruikt en dit wordt aanbevolen tenzij er een specifieke reden is om iets anders te gebruiken.

Voorbeeld: query naar de replicaserver (indien beschikbaar) en ophalen van resultaten als associatieve array:

$result = $database->query("SELECT id, example FROM {mytable}", [], [
  'target' => 'replica',
  'fetch' => PDO::FETCH_ASSOC,
]);

Het resultaatobject van query() kan worden gebruikt om alle geretourneerde rijen door te lopen. In het volgende voorbeeld bevat $result alle rijen en worden deze met fetchAssoc() één voor één opgehaald:

$sql = "SELECT name, quantity FROM goods WHERE vid = :vid";
$result = $database->query($sql, [':vid' => $vid]);
if ($result) {
  while ($row = $result->fetchAssoc()) {
    // Doe iets met:
    // $row['name']
    // $row['quantity']
  }
}

Complexe DELETE-query’s

Het gebruik van een statische query is een eenvoudige manier om een DELETE-query te schrijven die meerdere tabellen in één statement verwijdert.

Voorbeeld:

$database = \Drupal::database();
$database->query("DELETE {table1}, {table2} FROM {table1} INNER JOIN {table2} ON {table1}.id = {table2}.id WHERE {table1}.id=:recno", [":recno" => 2]);

(Verwijdert de rij zowel uit table1 als uit table2)