Referenz — Häufig gestellte Fragen zu PDO

Lesezeit: 6 Minuten

Was ist das?

Dies ist eine Liste häufig gestellter Fragen zu PHP-Datenobjekten

Warum ist das?

Da PDO einige Funktionen hat, die einem normalen PHP-Benutzer unbekannt sind, sind Fragen zu vorbereiteten Anweisungen und Fehlerbehandlung in PDO ziemlich häufig. Dies ist also nur ein Ort, an dem sie alle zu finden sind.

Was soll ich hier tun?

Wenn Ihre Frage mit dieser Liste eng abgestimmt wurde, finden Sie Ihre Frage unten und wenden Sie die Korrektur auf Ihren Code an. Es ist auch eine gute Idee, einen kurzen Blick auf andere Fragen zu werfen, um sich auf andere häufige Fallstricke vorzubereiten.

Die Liste

  • Die PDO-Abfrage schlägt fehl, aber ich kann keine Fehler sehen. Wie erhalte ich eine Fehlermeldung von PDO?
  • Wie kann ich vorbereitete Anweisungen mit dem LIKE-Operator verwenden?
  • Wie kann ich eine vorbereitete Anweisung für den IN()-Operator erstellen?
  • Kann ich eine vorbereitete PDO-Anweisung verwenden, um einen Bezeichner (einen Tabellen- oder Feldnamen) oder ein Syntaxschlüsselwort zu binden?
  • Die vorbereitete PDO-Anweisung verursacht einen Fehler in der LIMIT-Anweisung

Siehe auch

  • Referenz – Was bedeutet dieses Symbol in PHP?
  • Referenz – Was bedeutet dieser Fehler in PHP?
  • Referenz – Was ist der Gültigkeitsbereich von Variablen, auf welche Variablen kann von wo aus zugegriffen werden und was sind „undefinierte Variablen“-Fehler?

  • Ich denke, das passt nicht zu SO. Dies ist keine FAQ-Seite. Sie könnten es auf Ihrer Website platzieren. Zumindest die Posts sollten den Besitzer auf “Community-Wiki” ändern

    – hek2mgl

    13. April 2013 um 18:14 Uhr


  • Ich finde es sehr überraschend, dass ein 3-jähriger Benutzer mit 52.000 Wiederholungen so etwas mit 5 seiner eigenen Antworten postet. Sie haben genug Repräsentanten, um das PDO-Tag-Wiki zu bearbeiten. Das gehört da hin. Downvotes überall. Markierung zum Schließen.

    – Jo Frambach

    13. April 2013 um 19:55 Uhr

  • Haben Sie etwas dagegen, den Eigentümer dieser Frage und aller Antworten auf das Community-Wiki zu ändern? Genau dafür ist CW gedacht.

    – Jo Frambach

    13. April 2013 um 20:04 Uhr

  • Zu Ihrer Information, diese Frage wird derzeit unter diskutiert meta.stackexchange.com/questions/176417/…

    – Bart

    13. April 2013 um 21:14 Uhr


  • Aufgeteilt in einzelne Beiträge, stelle ich mir vor, dass diese Fragen äußerst nützlich wären. Ich unterstütze die Bemühungen, kanonische oder “Master”-Fragen zu erstellen, aber ich muss zustimmen, dass eine Gruppe wie diese nicht in das Format von SO passt, genauso wie es nicht der Fall wäre, wenn alle diese Fragen von einer Person in einem Beitrag gestellt worden wären eigentlich auf der Suche nach der Antwort.

    – jscs

    14. April 2013 um 18:21 Uhr

Die PDO-Abfrage schlägt fehl, aber ich kann keine Fehler sehen. Wie erhalte ich eine Fehlermeldung von PDO?

Um Datenbankfehler sehen zu können, muss man setzen PDO-Fehlermodus zu Ausnahmen. Ausnahmen sind in vielerlei Hinsicht besser als normale Fehler: Sie enthalten immer einen Stack-Trace, sie können mit try..catch abgefangen oder mit einem dedizierten Error-Handler behandelt werden. Und selbst wenn sie nicht behandelt werden, fungieren sie als reguläre PHP-Fehler, die alle wichtigen Informationen liefern und den seitenweiten Einstellungen für die Fehlerberichterstattung folgen.

Beachten Sie, dass die Einstellung dieses Modus als Verbindungsoption dazu führt, dass PDO auch Ausnahmen bei Verbindungsfehlern auslöst, was sehr wichtig ist.
Hier ist also ein Beispiel für die richtige Erstellung einer PDO-Verbindung:

$dsn = "mysql:host=$host;dbname=$db;charset=utf8";
$opt = array(
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    // other options 
);
$pdo = new PDO($dsn, $user, $pass, $opt);

Auf diese Weise verbunden, werden Sie immer über alle Datenbankfehler benachrichtigt, die während der Abfrageausführung aufgetreten sind. Beachten Sie, dass Sie PHP-Fehler im Allgemeinen sehen können müssen. Auf einer Live-Site müssen Sie in die Fehlerprotokolle schauen, also müssen die Einstellungen angepasst werden

error_reporting(E_ALL);
ini_set('display_errors',0);
ini_set('log_errors',1);

Auf einem lokalen Entwicklungsserver ist es in Ordnung, Fehler auf dem Bildschirm zu machen:

error_reporting(E_ALL);
ini_set('display_errors',1);

und natürlich sollten Sie niemals den Fehlerunterdrückungsoperator (@) vor Ihren PDO-Anweisungen.

Auch aufgrund vieler schlechter Beispiele, die Ihnen sagen, dass Sie jede PDO-Anweisung einschließen sollen try..catch Block, muss ich deutlich anmerken:

Verwenden Sie den try..catch-Operator NICHT nur, um eine Fehlermeldung anzuzeigen. Nicht erfasste Ausnahmen eignen sich bereits hervorragend für diesen Zweck, da sie sich genauso verhalten wie andere PHP-Fehler. Sie können das Verhalten also mithilfe von Site-weiten Einstellungen definieren. Sie erhalten Ihre Fehlermeldung ohne diesen nutzlosen Code. Eine bedingungslos wiederholte Fehlermeldung kann zwar einem potenziellen Angreifer einige sensible Informationen offenbaren, einen ehrlichen Besucher jedoch verwirren.

  • EIN benutzerdefinierter Ausnahmehandler können nachträglich hinzugefügt werden, sind aber nicht erforderlich. Besonders für neue Benutzer empfiehlt es sich, unbehandelte Ausnahmen zu verwenden, da sie äußerst informativ, hilfreich und sicher sind.
  • Verwenden try..catch nur dann, wenn Sie den Fehler selbst behandeln – sagen wir, um eine Transaktion rückgängig zu machen.

Die vorbereitete PDO-Anweisung verursacht einen Fehler in der LIMIT-Klausel

Aus Kompatibilitätsgründen wird PDO nur emulieren, nacheifern vorbereitete Anweisungen, indem Platzhalter durch tatsächliche Daten ersetzt werden, anstatt sie separat an den Server zu senden, sofern nicht anders angegeben. Und mit “fauler” Bindung (mit Array in execute()) behandelt PDO jeden Parameter als String. Als Ergebnis die vorbereitet LIMIT ?,? Abfrage wird LIMIT '10', '10' Dies ist eine ungültige Syntax, die dazu führt, dass die Abfrage fehlschlägt.

Auch dieses Problem kann gelöst werden

  • indem Sie den Emulationsmodus ausschalten (da MySQL alle Platzhalter richtig sortieren kann):

    $conn->setAttribute( PDO::ATTR_EMULATE_PREPARES, false );
    
  • durch explizites Binden und Setzen des richtigen Typs (PDO::PARAM_INT):

    $stm = $pdo->prepare('SELECT * FROM table LIMIT ?, ?');
    $stm->bindValue(1, $limit_from,PDO::PARAM_INT);
    $stm->bindValue(2, $per_page,PDO::PARAM_INT);
    $stm->execute();
    $data = $stm->fetchAll();
    

  • Danke, aber das ist nur und nur wenn Limit-Nutzung in PDO?

    – Alejandro L.

    16. Mai 2013 um 12:18 Uhr

Wie kann ich vorbereitete Anweisungen mit dem LIKE-Operator verwenden?

Vorbereitete Erklärung darstellen kann nur vollständiges Datenliteral. Kein Teil von Literal, kein komplexer Ausdruck oder Bezeichner. Aber entweder Nur Zeichenfolge oder Zahl. Eine sehr häufige Falle ist also eine Abfrage wie diese:

$sql = "SELECT * FROM t WHERE column LIKE '%?%'";

Wenn Sie ein wenig über diese Abfrage nachdenken, werden Sie verstehen, dass ein Fragezeichen innerhalb einfacher Anführungszeichen zu einem wörtlichen Fragezeichen wird, ohne eine besondere Bedeutung für die vorbereiteten Anweisungen.

Man muss also ein vollständiges String-Literal mit einer vorbereiteten Anweisung senden. Es gibt 2 Möglichkeiten:

  • entweder zuerst den VOLLSTÄNDIGEN Ausdruck vorbereiten:

    $name = "%$name%";
    $stm  = $pdo->prepare("SELECT * FROM table WHERE name LIKE ?");
    $stm->execute(array($name));
    $data = $stm->fetchAll();
    
  • oder verwenden Sie eine Verkettung innerhalb der Abfrage

    $sql = "SELECT * FROM t WHERE column LIKE concat('%',?,'%')";
    

obwohl letzteres zu aufgebläht erscheint.

  • Es sollte selbstverständlich sein, aber in den meisten Fällen werden Sie dem entkommen wollen %, _ und alle anderen Engine-unterstützten Platzhalter in $name bevor Sie es in die Abfrage einfügen.

    – DCoder

    13. April 2013 um 18:42 Uhr

  • @DCoder: +1, nur der Vollständigkeit halber und da dies eine Referenzfrage ist: addcslashes($name, '%_\\');.

    – Alix Axel

    3. Juni 2013 um 13:24 Uhr


992940cookie-checkReferenz — Häufig gestellte Fragen zu PDO

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy