SQL mit eZDB, sicher
Diese Seite richtet sich an PHP-Entwickler, die SQL schreiben. Exponential erreicht jede Datenbank über eZDB
(lib/ezdb/classes/ezdb.php), das einen Treiber zurückgibt, der eZDBInterface (lib/ezdb/classes/ezdbinterface.php)
implementiert. Die Treiberschnittstelle hat keine gebundenen Parameter für beliebiges SQL, sodass die Sicherheit aus
zwei Gewohnheiten kommt: jeden String maskieren, jede Zahl casten.
Inhalt
- Die Verbindung holen
- Lesen
- Schreiben
- Maskieren: die zwei Regeln
- Wertelisten
- Transaktionen
- Rückgabewerte
- Wann Sie kein SQL schreiben sollten
Die Verbindung holen
$db = eZDB::instance();eZDB::instance() gibt die gemeinsam genutzte Verbindung für die [DatabaseSettings] des aktuellen Siteaccess zurück.
Legen Sie mit forceNewInstance keine eigene Verbindung an, sofern Sie nicht wirklich eine zweite brauchen; das kostet
eine Verbindung und entzieht sich dem Transaktionszustand der Anfrage.
Lesen
$userID = (int)$userID;
$rows = $db->arrayQuery(
"SELECT id, title, created FROM acme_report_item WHERE user_id = $userID ORDER BY created DESC",
array( 'offset' => 0, 'limit' => 20 )
);
foreach ( $rows as $row )
{
// $row['id'], $row['title'], $row['created'] are strings (or null)
}
$titles = $db->arrayQuery( "SELECT title FROM acme_report_item WHERE user_id = $userID",
array( 'column' => 'title' ) ); // a flat list of one columnÜbergeben Sie limit und offset als Parameter, statt LIMIT ins SQL zu schreiben: Der Treiber schreibt die Syntax,
die seine Datenbank versteht (Oracle und SQLite unterscheiden sich von MySQL).
Schreiben
$title = $db->escapeString( $title );
$now = time();
$db->query( "INSERT INTO acme_report_item ( user_id, title, created ) VALUES ( $userID, '$title', $now )" );
$newID = $db->lastSerialID( 'acme_report_item', 'id' );Maskieren: die zwei Regeln
| Wert | Regel | Beispiel |
|---|---|---|
| String | $db->escapeString(), in einfachen Anführungszeichen | "... WHERE title = '" . $db->escapeString( $title ) . "'" |
| Ganzzahl | (int) | "... WHERE id = " . (int)$id |
| Gleitkommazahl | (float) | "... WHERE amount > " . (float)$min |
| Spalten- oder Tabellenname aus der Eingabe | eine Allow-Liste, niemals die Eingabe selbst | in_array( $sort, array( 'title', 'created' ), true ) |
| Sortierrichtung | eine feste Auswahl | $dir = $desc ? 'DESC' : 'ASC'; |
Casten oder maskieren Sie so nah am SQL wie möglich, auch wenn der Wert „bereits geprüft wurde“: Die nächste Änderung am
umgebenden Code kann die Prüfung entfernen. Werte aus $Params, eZHTTPTool, Einstellungen, Importen und der
Datenbank selbst sind alle Eingaben (Eingaben validieren und casten).
Wertelisten
$ids = array_map( 'intval', $ids );
$in = $db->generateSQLINStatement( $ids, 'id', false, true, 'int' ); // id IN ( 1, 2, 3 ); drivers may override it
$rows = $db->arrayQuery( "SELECT id, title FROM acme_report_item WHERE $in" );Mit einem Typ ('int') castet generateSQLINStatement() jedes Element über implodeWithTypeCast(); lassen Sie den
Treiber die Anweisung bauen, statt sie selbst zusammenzusetzen, da ein Treiber sie für seine Datenbank anders schreiben
kann.
Transaktionen
$db->begin();
$item->store();
$log->store();
$db->commit();begin()undcommit()lassen sich verschachteln: Ein inneres Paar innerhalb eines äußeren wird nur gezählt (transactionCounter()), und das äußerecommit()committet. Jedesbegin()braucht auf jedem Pfad genau eincommit()oderrollback(), einschließlich vorzeitiger Rückgaben und Exceptions.- Transaktionen werden nur verwendet, wenn
[DatabaseSettings] Transactions=enabled. - Halten Sie Transaktionen kurz; unter SQLite wartet ein Schreiber auf die Schreiber vor ihm (SQLite-Transaktionen).
Rückgabewerte
| Aufruf | Gibt zurück |
|---|---|
query() | true oder false für die meisten Anweisungen |
arrayQuery() | ein Array von Zeilen (leer, wenn nichts passt) |
lastSerialID() | die neue ID nach einem Insert |
Prüfen Sie das Ergebnis von query(), wenn es darauf ankommt. Verlassen Sie sich nicht auf Sitzungsvariablen
SET @var := ... über query(); für Inserts, die die neue ID brauchen, setzt eZPersistentObject::store() sie für
Sie. Ergebnisse unterscheiden sich in Grenzfällen auch zwischen Engines, zum Beispiel ein leeres Ergebnis und eine
fehlgeschlagene Anweisung beim MongoDB-Adapter (Code für jede unterstützte Datenbank).
Wann Sie kein SQL schreiben sollten
| Bedarf | Besser |
|---|---|
| Zeilen Ihrer eigenen Tabelle | Bedingungen von eZPersistentObject, für Sie maskiert (Definitionen persistenter Objekte im Detail) |
| Inhalte | eZContentObjectTreeNode::subTreeByNodeID() und die Content-API (Die Content-API in PHP) |
| das Schema | .dba-Dateien und der Schema-Handler (Datenbankschema und .dba-Dateien) |
Verwandte Seiten
- eZDB-Referenz
- Datenbankzugriff und SQL
- Standard für Datenbanken und SQL
- Freie Dokumentation: diese Seite darf unter der GNU FDL 1.3 frei kopiert, übersetzt und verbessert werden.
Werden Sie Exponential-Partner
Partner teilen ihre Informationen, stellen Mittel bereit, geben Beiträge zurück und entwickeln die Produkte mit uns, und so wächst Exponential. Eine Partner-Website und ein Dashboard sind für Mitte 2027 geplant: Werden Sie noch heute Partner, damit wir schneller wachsen und neue Funktionen früher liefern.