Ankündigung

Einklappen
Keine Ankündigung bisher.

PDO - Beitrag

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • hausl
    hat ein Thema erstellt PDO - Beitrag.

    PDO - Beitrag

    Geht um diesen Beitrag: http://php-de.github.io/jumpto/pdo/

    Nachdem es noch den einen oder anderen Input gab, verlagere ich das PN mal hier her. Ich steige beim letzten Beitrag mal vom Arne ein, die Punkte von davor sind soweit alle umgesetzt, falls noch etwas offen ist oder auffällt einfach hier anmerken. Danke!

    Zitat von Arne Drews
    Finde ich soweit gut.

    Anmerkungen:
    1. Bei der Wiederverwendung der Verbindung solltest Du evtl. für den einen oder anderen Laien den Funktionsaufruf mit reinschreiben.
    Ich könnte mir vorstellen, daß einige das // oder überlesen und meinen, daß das zusammengehört.

    2. Nur mal in den Raum geworfen: Wird das letzte Beispiel Multi Execute benötigt?
    Eigentlich zeigt das ja nur die Arbeitsweise von bindParam. Ich finde nicht, daß in der Wissensammlung Beispiele sein sollten mit dem Hinweis: "Aber bitte nicht so machen!".

    3. Dann eine Frage für mich zum Verständnis:
    Die PreparedStatements funnktionieren bei PDO meiner Meinung nach so gut, weil ich über bspw. bindParam() den Datentyp angeben kann.
    Das ist mir bei der Verwendung von execute( $array ) nicht möglich. Daher habe ich das eigentlich bisher nie verwendet.
    Wie zuverlässig erkennt er denn, welchen Datentyp ich übergebe?

  • hausl
    antwortet
    Zitat von hausl Beitrag anzeigen
    1. PDO::ATTR_EMULATE_PREPARES => false, mit in Verbindungserstellung aufnehmen, gem. #19

    2. Den Teil mit nackten Queries (ohne Prep.Statem.) entfernen (speziell weil bestimmt Anfänger Copy&Paste verwenden). Dann ist es explizit im Code ersichtlich was verwendet wird und die DB-Zugriffe es ist einheitlich Durchgängig.

    3. Keine Backticks, weil man dadurch die Portabilität verliert, jedoch Hinweis das man auf die reservierten Keywords achten muss, die ja vermutlich auch je DBMS wieder varrieren können.
    Habe den Beitrag eben mal ensprechend überarbeitet ... bitte um Feedback wenn nochwas zu ergänzen wäre. Danke!

    http://php-de.github.io/jumpto/pdo/

    LG

    Einen Kommentar schreiben:


  • jspit
    antwortet
    Ich vermute, du hast noch PDO bindValue mit PDO::PARAM_INT für LIMIT im Hinterkopf. Dort hat aber auch schon dingsda einige wertvolle Hinweise gegeben.

    Einen Kommentar schreiben:


  • Arne Drews
    antwortet
    Und ich habe gedacht, der Hinweis darauf, daß es per default auf true steht, kam von Dir, jspit
    Finde den Post grad nicht auf die Schnelle, aber mir war so?!

    Einen Kommentar schreiben:


  • hausl
    antwortet
    Ok, danke. Somit nehme ich zusammenfassend für den Artikel mit:

    1. PDO::ATTR_EMULATE_PREPARES => false, mit in Verbindungserstellung aufnehmen, gem. #19

    2. Den Teil mit nackten Queries (ohne Prep.Statem.) entfernen (speziell weil bestimmt Anfänger Copy&Paste verwenden). Dann ist es explizit im Code ersichtlich was verwendet wird und die DB-Zugriffe es ist einheitlich Durchgängig.

    3. Keine Backticks, weil man dadurch die Portabilität verliert, jedoch Hinweis das man auf die reservierten Keywords achten muss, die ja vermutlich auch je DBMS wieder varrieren können.

    Einen Kommentar schreiben:


  • jspit
    antwortet
    Bin bisher immer davon ausgegangen, daß PDO::ATTR_EMULATE_PREPARES für MySQL per Defaultwert auf false steht und ein Setzen überflüssig ist.
    Habe den obigen Beitrag von Fräulein Dingsda zum Anlass genommen, dies mal zu überprüfen und mußte feststellen, das es bei den mir verfügbaren Systemen leider nicht auf false steht.

    Einen Kommentar schreiben:


  • dingsda
    antwortet
    Wenn man bei PDO mit mysql ATTR_EMULATE_PREPARES ausgeschaltet hat wird sowieso wirklich jede query als prepared statement geschickt *. also auch welche, wie
    PHP-Code:
    $result $dbconn->query('select column from uselesstable'); 
    insofern kann man wirklich gleich für alles prepared statements nehmen.

    Edit 1: *kann man gut sehen, wenn man den query log von mysql anschaut. testcode:
    PHP-Code:
    $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
    $stmt=$pdo->query("select 1");
    var_dump($stmt->fetchAll(PDO::FETCH_ASSOC)); 
    im query-log findet man dann:
    Code:
               Prepare    select 1
               Execute    select 1
    schaltet man emulate_prepares an findet man im query log stattdessen
    Code:
               Query    select 1
    zusätzlich hat sich auch der datentyp verändert von der 1, die wir fetchen. ist emulate_prepares ausgeschaltet zeigt das var_dump
    Code:
    array(1) { [0]=> array(1) { [1]=> int(1) } }
    bei eingeschaltetem emulate_prepares dagegen:
    Code:
    array(1) { [0]=> array(1) { [1]=> string(1) "1" } }
    Edit 2: schade, dass nun doch attr_emulate_prepares nicht mit im artikel ist. imho gehört das in den ersten code zum verbindungsaufbau:
    PHP-Code:
    $dsn  'mysql:dbname=test;host=localhost;charset=utf8';
    $user 'root';
    $pass '';
    $options = array(
        
    PDO::ATTR_EMULATE_PREPARES => false,
        
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ
    );
    $pdo = new PDO($dsn$user$pass$options); 

    Einen Kommentar schreiben:


  • tr0y
    antwortet
    Es ist performance-technisch egal ob du prepared Statements für basic queries nimmst oder reguläre. Wenn du im Mikrosekunden-Bereich optimieren musst, lief etwas vollkommen falsch.

    Einen Kommentar schreiben:


  • VPh
    antwortet
    Ja.

    Syntax etwas simpler - Ein Funktionsaufruf weniger,
    Ausführung minimal schneller - Zeit für Preparen mainly; keine Ahnung ob ohne Parameter auch nochmal die zweite Tour durch den MySQL-Optimizer gemacht wird; evtl. DBMS-spezfische Performance-Geschichten, alte MySQL-Versionen konnten PS nicht in den Query-Cache aufnehmen z.B.
    MetaKommunikation im Code(?) - einfache Funktion für 'einfache' Operationen, komplexere Funktionen für komplexere Operationen wie eben Userinput oder mehrfache gleiche Abfrage mit wechselnden Parametern

    Das sind kleine Extras, die man über den einfacheren Weg erhält. Ich sehe da noch keinen Nachteil.

    Einen Kommentar schreiben:


  • fireweasel
    antwortet
    Zitat von VPh Beitrag anzeigen
    Ist bei Queries ohne Kontextwechsel doch nur unnötiger Overhead.
    Diesen "Overhead" kannst du dann beseitigen, wenn du wirklich welchen gemessen hast.

    Was meinst du mit "Queries ohne Kontextwechsel"? Ein Statement ohne Parameter? Es mag sein, dass ...
    PHP-Code:
    $dbconn = new PDO();
    $result $dbconn->query('select column from uselesstable'); 
    ein paar Microsekunden schneller ist als ...
    PHP-Code:
    $dbconn = new PDO();
    (
    $stmt $dbconn->prepare('select column from uselesstable'))->execute(); 
    ..., aber das funktioniert halt auch nur dann, wenn das jeweilige Stück Quellcode ausschließlich festverdrahtetes SQL abarbeitet.

    Einen Kommentar schreiben:


  • VPh
    antwortet
    Man sollte unter PDO immer Prepared Statements verwenden
    Ist bei Queries ohne Kontextwechsel doch nur unnötiger Overhead.

    oder Backticks generell meiden.
    Jo, würde ich so unterstützen. Vielleicht dazu noch paar Richtlinien zur Namensgebung von Tabellen und Spalten. 'am besten keine Sonderzeichen, keine reservierten wörter...'

    Einen Kommentar schreiben:


  • Arne Drews
    antwortet
    Für den Vorteil, das DBMS wechseln zu können, gebe ich Dir im Punkt Backticks recht!
    PreparedStatements würde ich ebenfalls als grundlegend ansehen! Warum auf eine Möglichkeit verzichten, die SQL-Injection größtenteils schon verhindert und keinen verhältnismäßig größeren Aufwand für den Entwickler bedeuten?!

    Einen Kommentar schreiben:


  • hausl
    antwortet
    Ich würde zu dem PDO Beitrag gerne noch etwas diskutieren - speziell zum Punkt "einfache Query ohne Parameter"

    Ich stelle mal folgende Aussage in den Raum - würde gerne dazu eure Meiungen hören.

    Man sollte unter PDO immer Prepared Statements verwenden, oder Backticks generell meiden. Tut man dies nicht verliert man einen der Vorteile von PDO, nämlich die theoretische Möglichkeit, relativ leicht das DBMS zu wechseln, da Backticks zB unter MS-SQL, Postgres, Oracle, etc .. per default nicht funktionieren. Somit entweder oder.

    Einen Kommentar schreiben:


  • hausl
    antwortet
    Ich wäre von meiner Seite durch, falls was auffällt, bitte einfach hier posten. Danke!

    http://php-de.github.io/jumpto/pdo/

    LG

    Einen Kommentar schreiben:


  • hausl
    antwortet
    Zitat von Arne Drews Beitrag anzeigen
    Richtig. Aber die Werte werden je Datentyp anders behandelt. also warum will ich alle Werte als String verarbeiten lassen, wenn es vielleicht keine sind.
    Gerade versucht, hier wird korrekt NULL in die DB geschrieben (DB-Defaultwert wäre ein anderer, nur sicherheitshalber erwähnt).

    PHP-Code:
    $sql "INSERT INTO `user` (`username`, `gender`) VALUES (:username, :gender)";
    $stmt $pdo->prepare($sql);

    $username 'Sarah';
    $gender NULL;

    $aParams = array(':username' => $username':gender' => $gender);
    $stmt->execute($aParams); 

    Einen Kommentar schreiben:

Lädt...
X