Der-Dennis: Frage zum Wiki-Artikel „PHP MySQL API“

3 31

Frage zum Wiki-Artikel „PHP MySQL API“

  1. 0
    1. 0
      1. 2
  2. 0
    1. 1
    2. 0
      1. 0
        1. 0
      2. 4

        Ausrichtung des Wiki

  3. 0
    1. 0
      1. 0
        1. 0
        2. 0
          1. 0
  4. 0
    1. 1
  5. 0

    Feedback-Schleife 1

    1. 0
      1. 0
  6. 0
    1. 0
      1. 0
        1. 0
          1. 0
            1. 0
            2. 0
  7. 3
    1. 0
      1. 0

problematische Seite

Hallo zusammen,

ich habe eine erste Version des Artikels zu den PHP MySQL APIs fertiggestellt.

Der Artikel soll …
… einen kurzen Überblick über die APIs geben und
… eine kleine Umstiegshilfe von der MySQL-API auf eine andere API bereitstellen

Der Artikel soll kein …
… Anfänger- oder Fortgeschrittenentutorial sein und nicht
… zeigen, was man mit den APIs alles machen kann

Über Feedback würde ich mich freuen.

Vorstellen könnte ich mir, dass es später mal noch ein Anfänger- und Fortgeschrittenentutorial geben könnte. Im Anfängertutorial dann z.B. anhand eines konkreten Beispiels zeigen, wie das mit den Datenbanken funktioniert. Und im Fortgeschrittenen-Teil dann evtl. OOP und ORM. Mit diesen drei Artikeln würde man meiner Meinung nach das Thema schon recht gut abgehandelt haben.

Gruß
Dennis

akzeptierte Antworten

  1. problematische Seite

    Der Artikel soll …
    … eine kleine Umstiegshilfe von der MySQL-API auf eine andere API bereitstellen

    Mir gefällt sehr wie Du das jeweils untereinandergestellt hast. Das ist extrem hilfreich.

    Was mir fehlt ist die Fehlerbehandlung last_error u. co. sowie Ergebniskontrolle wie affected_rows und dann noch num_rows.

    1. problematische Seite

      Hallo Tagwächter,

      vielen Dank, dass Du Dir den Artikel durchgelesen hast und für Dein Feedback!

      Der Artikel soll …
      … eine kleine Umstiegshilfe von der MySQL-API auf eine andere API bereitstellen

      Mir gefällt sehr wie Du das jeweils untereinandergestellt hast. Das ist extrem hilfreich.

      Das freut mich.

      Was mir fehlt ist die Fehlerbehandlung last_error u. co. sowie Ergebniskontrolle wie affected_rows und dann noch num_rows.

      Das kann ich gerne noch hinzufügen. Ich habe dann jetzt noch

      • connect_error
      • error
      • affected_rows
      • num_rows

      Fällt Dir sonst eine Funktion ein, die an der Stelle wichtig wäre?

      Danke nochmal und Gruß
      Dennis

      1. problematische Seite

        Das freut mich.

        ich denke übrigens auch, dass Dein Wikibeitrag ganz stark in die Zeit gehört, denn der Umstieg auf PHP7 und damit der Ausstieg aus der Nutzung der alten mysql-Funktionen steht einfach für viele an und denen hast Du ein gutes Rezeptbuch gegeben.

        Und solange es im Wiki Beiträge über PHP gibt ist der Beitrag dort auch alles andere als "deplaziert".

  2. problematische Seite

    Hallo Dennis,

    ich finde den Artikel als Einstieg prima. Du hast Dir viel Arbeit gemacht. Man muss natürlich grundsätzlich immer überlegen, ob ein solches Werk im Kontext von SelfHTML sinnvoll ist oder ob man auf gute, fertige Artikel im wilden weiten Web verweisen kann. Ob sich viel Arbeit für ein "Me too" Produkt lohnt, muss man immer gut überlegen. Aus meiner Sicht (aber das ist meine Privatmeinung) liegt der Schwerpunkt des Wiki im Browser, d.h. HTML, CSS und Javascript. Da steht SelfHTML in harter Konkurrenz zu MDN, was das Label "beste Doku" angeht, und ist im Rückstand (mangels Manpower?). Ob man dann ein weiteres Feld eröffnet, statt das bestehende Feld zu stabilisieren, ist eine Überlegung wert.

    Unter der Annahme, dass die Überlegung zu Gunsten einer PHP Einführung endet, hätte ich folgende Hinweise.

    • die Formulierung "die Auswahl der API erfolgt in Bezug auf den konkreten Anwendungsfall" würde ich so nicht stehen lassen. "Anwendungsfall" bezeichnet für mich die fachliche Anforderung, die umzusetzen ist, und da sind mysqli/proc, mysqli/oo und PDO gleichwerting. Performance ist ebenfalls kein Kriterium, weil alle Anbindungen leichtgewichtige Hüllen um den eigentlichen C-Treiber sind. Auswahlkriterium ist eher die Vorliebe des Programmierers. Wenn man ein PHP-Programm objektorientiert aufzieht, wird man auch die OO-Schnittstelle von MySQLi nutzen wollen, oder gleich PDO. Wenn man ohne Objekte arbeitet bzw. von mysql auf mysqli umstellt, verwendet man die prozedurale Kapsel.
    • mysql wurde abgelöst, weil es Sicherheitslücken hat? Hast Du dafür einen Quelle? Hier steht, was in mysqli besser wurde, aber von geschlossenen Sicherheitslücken steht da nichts. Auf entwickler.de habe ich einen Hinweis vom PHP 5.3 Release Manager - Johannes Schlüter - gefunden: The old mysql extension, ext/mysql, is old. The code goes back to the early days of PHP and MySQL and embraces some bad design decisions. For example if no explicit connection resource is passed all functions will try to use the last connection which was being used..
    • die prozedurale Variante von mysqli weicht bei connect etwas von der OO-Schicht ab, new mysqli() liefert immer ein mysqli-Objekt, aber mysqli_connect liefert FALSE wenn ein Fehler auftritt. Deswegen bekommen mysqli_connect_errno() und mysqli_connect_error() auch keinen Parameter (siehe Doku, da steht void). Und um zu prüfen, ob $link = mysqli_connect(...) fehlschlug, soll man if (!$link) testen. (siehe Beispiel hier)
    • sprintf: Ist das in PHP das Mittel der Wahl? Ich kenne hauptsächlich Verkettungen per . Operator oder string parsing ("Hallo $dings")
    • In der mysqli-Beschreibung sprichst Du korrekt vom Escaping für den Kontextwechsel. Aber im PDO Beispiel verwendest Du ein prepared statement - wo man nicht escapen muss. Deshalb ist es meiner Meinung nach falsch, dort von einem Kontextwechsel zu sprechen. Er ist hier nicht nötig, weil die Parameter nicht ins SQL eingebettet werden. Sie bleiben in ihrem eigenen Kontext erhalten. Statt dessen sollte darauf hingewiesen werden, dass prepared statements wegen der SQL Parameter kein Escaping benötigen.
    • Du könntest darauf hinweisen, dass auch mysqli prepared statements unterstützt (aber schlechter, weil es keine benannten Parameter gibt) und dass man in PDO auch eine Funktion für Escaping im Kontextwechsel hat, wenn man keine prepared statements verwenden will (PDO::quote). Wenn man das vollständig zeigen will, muss man das Beispiel allerdings fünfmal statt dreimal bringen :)

    Rolf

    1. problematische Seite

      Tach!

      • mysql wurde abgelöst, weil es Sicherheitslücken hat? [...] `The old mysql extension, ext/mysql, is old. [...]

      Ja, das Alter und weil damit die neueren Möglichkeiten (die auch schon wieder recht alt, aber noch aktuell sind) nicht realisierbar waren, beispielsweise Prepared Statements und Stored Procedures.

      • die prozedurale Variante von mysqli weicht bei connect etwas von der OO-Schicht ab, new mysqli() liefert immer ein mysqli-Objekt, aber mysqli_connect liefert FALSE wenn ein Fehler auftritt.

      Hier weicht wohl eher das OOP von der herkömmlichen PHP-Art und -Weise ab, Misserfolge über den Rückgabewert bekanntzugeben. Das geht bei new nicht, weil das immer das erzeugte Objekt zurückgibt. Exception werfen ginge, aber das muss auch ohne gehen, für die, die keine Exceptions verwenden.

      • sprintf: Ist das in PHP das Mittel der Wahl? Ich kenne hauptsächlich Verkettungen per . Operator oder string parsing ("Hallo $dings")

      sprintf ist das Mittel der Wahl, wenn man die Statement-Strings nicht auseinanderreißen und verketten möchte. Das Statement auf einen kompletten Blick zu haben, ist doch meist vorteilhafter, besonders wenn "Hallo $dings" nicht geht, weil $dings noch durch die Maskierfunktion geschickt werden muss.

      dedlfix.

    2. problematische Seite

      Hallo Rolf,

      auch Dir vielen Dank, dass Du Dir den Artikel durchgelesen hast und für Dein Feedback!

      Aus meiner Sicht (aber das ist meine Privatmeinung) liegt der Schwerpunkt des Wiki im Browser, d.h. HTML, CSS und Javascript. Da steht SelfHTML in harter Konkurrenz zu MDN, was das Label "beste Doku" angeht, und ist im Rückstand (mangels Manpower?). Ob man dann ein weiteres Feld eröffnet, statt das bestehende Feld zu stabilisieren, ist eine Überlegung wert.

      Ich ging bzw. gehe davon aus, dass das gewünscht war/ist. Zumindest wurde immer wieder angesprochen, dass insbesondere der PHP-Bereich mal etwas ausgebaut werden sollte, weil HTML, CSS und JS jetzt einigermaßen vollständig sind. Vielleicht sollte man das sonst nochmal hier im Forum thematisieren?

      • die Formulierung "die Auswahl der API erfolgt in Bezug auf den konkreten Anwendungsfall" würde ich so nicht stehen lassen. "Anwendungsfall" bezeichnet für mich die fachliche Anforderung, die umzusetzen ist, und da sind mysqli/proc, mysqli/oo und PDO gleichwerting. Performance ist ebenfalls kein Kriterium, weil alle Anbindungen leichtgewichtige Hüllen um den eigentlichen C-Treiber sind. Auswahlkriterium ist eher die Vorliebe des Programmierers. Wenn man ein PHP-Programm objektorientiert aufzieht, wird man auch die OO-Schnittstelle von MySQLi nutzen wollen, oder gleich PDO. Wenn man ohne Objekte arbeitet bzw. von mysql auf mysqli umstellt, verwendet man die prozedurale Kapsel.

      Ja, korrekt. „Vorliebe des Programmierers“ trifft es. Werde ich ändern.

      • mysql wurde abgelöst, weil es Sicherheitslücken hat? Hast Du dafür einen Quelle?

      Ja, Quellen sind auch dort angegeben. Zumindest ganz grob. Ich sprach aber nicht von „Lücken“, sondern allgemein von Sicherheit. Hoffe ich auf jeden Fall, weil konkrete Lücken sind mir nicht bekannt. Die Entwickler haben lange darüber diskutiert, was mit der Extension passieren soll. Anfangs stand vorallem die Sicherheit im Vordergrund, später dann neuere MySQL-Features, die mit der API nicht genutzt werden können und schließlich, dass man da auch nicht mehr viel Warten kann, weil das Ding immerhin schon fast 15 Jahre alt ist. Die Sicherheit ist auf jeden Fall mindestens als unterdurchschnittlich eingestuft. Auch im RFC von 2011 wird bereits davon gesprochen: „The documentation team is discussing the database security situation, and educating users to move away from the commonly used ext/mysql extension is part of this.“

      • die prozedurale Variante von mysqli weicht bei connect etwas von der OO-Schicht ab, new mysqli() liefert immer ein mysqli-Objekt, aber mysqli_connect liefert FALSE wenn ein Fehler auftritt. Deswegen bekommen mysqli_connect_errno() und mysqli_connect_error() auch keinen Parameter (siehe Doku, da steht void).

      Korrekt. Da habe ich nicht aufgepasst.

      Und um zu prüfen, ob $link = mysqli_connect(...) fehlschlug, soll man if (!$link) testen. (siehe Beispiel hier)

      Ist das so? Kann ich zumindest aus der Doku ehrlich gesagt nirgendwo rauslesen.

      • sprintf: Ist das in PHP das Mittel der Wahl? Ich kenne hauptsächlich Verkettungen per . Operator oder string parsing ("Hallo $dings")

      Es ist zumindest nicht unüblich. Ich persönlich finde das auch etwas übersichtlicher

      $sql = sprintf("SELECT ... WHERE a = '%s' AND b ='%s'",
          $mysqli->real_escape_string($a),
          $mysqli->real_escape_string($b));
      

      als das

      $sql = "SELECT ... WHERE a = '" . $mysqli->real_escape_string($a) . "' AND b ='" . $mysqli->real_escape_string($b) . "'";
      
      • In der mysqli-Beschreibung sprichst Du korrekt vom Escaping für den Kontextwechsel. Aber im PDO Beispiel verwendest Du ein prepared statement - wo man nicht escapen muss. Deshalb ist es meiner Meinung nach falsch, dort von einem Kontextwechsel zu sprechen. Er ist hier nicht nötig, weil die Parameter nicht ins SQL eingebettet werden. Sie bleiben in ihrem eigenen Kontext erhalten. Statt dessen sollte darauf hingewiesen werden, dass prepared statements wegen der SQL Parameter kein Escaping benötigen.

      Ja, ist richtig, kann man auch so machen. Solche Vereinfachungen habe ich an einigen Stellen drin, auch wenn sie technisch nicht komplett richtig sind. Ich will aber eigentlich keinen komplett neuen Kontextwechsel-Artikel schreiben oder ein Prepared Statements-Tutorial da einbauen. Die Idee war, einen groben Überblick zu geben und den Lesern nur trotzdem immer wieder klarzumachen, dass man auf sowas zu achten hat. Kann man ja nicht oft genug machen. Muss ich mal überlegen.

      • Du könntest darauf hinweisen, dass auch mysqli prepared statements unterstützt (aber schlechter, weil es keine benannten Parameter gibt)

      Ja. Das hab ich rausgelassen, weil ich ja nur eine grobe Übersicht geben will und - wie im ersten Posting geschrieben - eben nicht zeigen möchte, was man alles mit den APIs so machen kann.

      und dass man in PDO auch eine Funktion für Escaping im Kontextwechsel hat, wenn man keine prepared statements verwenden will (PDO::quote).

      Hab ich rausgelassen, weil die Doku schreibt, dass man quote zugunsten von Prepared Statements nicht nutzen sollte. Ich hatte das vorher drin, damit es besser vergleichbar mit den anderen APIs ist. Hab's dann aber doch für Prepared Statements nicht genommen, da das so ja schon sinnvoller ist.

      Wenn man das vollständig zeigen will, muss man das Beispiel allerdings fünfmal statt dreimal bringen :)

      Wenn das mal ausreicht :-)

      Vielen Dank und Gruß
      Dennis

      1. problematische Seite

        Tach!

        • mysql wurde abgelöst, weil es Sicherheitslücken hat? Hast Du dafür einen Quelle?

        Ja, Quellen sind auch dort angegeben. Zumindest ganz grob. Ich sprach aber nicht von „Lücken“, sondern allgemein von Sicherheit. Hoffe ich auf jeden Fall, weil konkrete Lücken sind mir nicht bekannt.

        Sicherheit verbindet jeder mit Lücken. Ich würde das nicht so behaupten, auch wenn es vielleicht tatsächlich stimmt. Das wichtigere Argument hier ist das Wegfallen aufgrund Überalterung und unnötig hohem Pflegeaufwand bei zwei Extensions.

        dedlfix.

        1. problematische Seite

          Hallo dedlfix,

          Sicherheit verbindet jeder mit Lücken. Ich würde das nicht so behaupten, auch wenn es vielleicht tatsächlich stimmt. Das wichtigere Argument hier ist das Wegfallen aufgrund Überalterung und unnötig hohem Pflegeaufwand bei zwei Extensions.

          ok, dann kommt das raus.

          Gruß
          Dennis

      2. problematische Seite

        Servus!

        Aus meiner Sicht (aber das ist meine Privatmeinung) liegt der Schwerpunkt des Wiki im Browser, d.h. HTML, CSS und Javascript. Da steht SelfHTML in harter Konkurrenz zu MDN, was das Label "beste Doku" angeht, und ist im Rückstand (mangels Manpower?). Ob man dann ein weiteres Feld eröffnet, statt das bestehende Feld zu stabilisieren, ist eine Überlegung wert.

        Ich ging bzw. gehe davon aus, dass das gewünscht war/ist. Zumindest wurde immer wieder angesprochen, dass insbesondere der PHP-Bereich mal etwas ausgebaut werden sollte, weil HTML, CSS und JS jetzt einigermaßen vollständig sind. Vielleicht sollte man das sonst nochmal hier im Forum thematisieren?

        @Rolf b , da gehst du schon mit der Mehrheit der Selfer d'accord. Andererseits beziehen sich ein großer Teil der Fragen im Forum auf PHP, Webserver im Allgemeinen und Apache im Besonderen. Diese Fragen werden ja auch beantwortet und da ist es nur logisch, wenn wir diese Bereiche, die vom Ansatz her bereits vorhanden sind, auch pflegen und erweitern.

        Mit der MDN können wir, wie die bereits richtig gesagt hast, aufgrund der fehlenden Manpower nicht mithalten. Basis für die Self-Doku war der Mangel an Spezifikationen und Dokumentationen, den es heute so nicht mehr gibt. Allerdings benötigt SELFHTML aber nicht für jede CSS-Eigenschaft oder API-Methode eine eigene Seite, wie es die MDN, die in ihrer englischen Version oft nur die Spec kopiert hat, besitzt.

        Ich sehe den Schwerpunkt von SELFHTML in den Tutorials, wo neben HTML, CSS und JavaScript auch die Grundlagen der Programmierlogik erklärt werden.

        Ein wichtiger Punkt ist die Pflege des Vorhandenen. Hier sind wir mit der Einbindung von Caniuse im Browsersupport immer aktuell, während viele Artikel der MDN trotz dutzender Bearbeiter nicht gepflegt (FF3.6, alle anderen Browser seit 2010 nicht aktualisiert) oder fehlerhaft (bzw. durch Computer) übersetzt werden. Es ist aber immer wieder nötig, unsere Seiten zu durchforsten und sowohl inhaltlich als auch stilistisch zu verbesssern.

        Es ist immer einfacher geworden, einen Blog, ein Forum oder sogar ein Wiki aufzusetzen. Damit einhergehend hat aber auch eine Framgentierung der Communities stattgefunden, die es m.E. nach besonders Anfängern erschwert, einen Anlaufpaunkt für ihre Fragen zu finden. Durch eine Selbstbeschränkung unsererseits würde sich das noch verstärken.

        Deshalb vielen Dank an @Der-Dennis für seinen Artikel, der ja aus der Aktualisierung des Kontextwechsel-Artikels (von 2009) heraus geboren wurde!

        Herzliche Grüße

        Matthias Scharwies

        --
        Es gibt viel zu tun: ToDo-Liste
  3. problematische Seite

    Tach!

    Auch ich würde nicht "je nach Anwendungsfall" sondern "nach Vorliebe" nehmen, weil funktional sich mysqli und PDO nicht viel nehmen, jedenfalls nicht für die Anwendungsfälle der Zielgruppe. Für bestimmte, eher selten verwendete Dinge braucht man mysqlis auf MySQL zugeschnittene Funktionalität. PDO ist eher als einheitliche Schnittstelle für mehrere DBMS als für die Verwendung bei datenbankspezifischen Eigenheiten.

    Eine Umstiegshilfe findet sich unten.

    Unten, oben, hier, dort ... sind alles keine gescheiten Linkbezeichnungen. "Informationen dazu in der Umstiegshilfe." wäre schon etwas besser.

    Abkürzungen und Fachbegriffe sollte nochmal betrachtet werden, ob man da nicht noch anfängerfreundliche Kurzerklärungen/Übersetzungen hinzufügen kann. Ist ja nicht jedem geläufig, was zum Beispiel API heißt.

    Maskieren und sprintf(): Ich würde da nicht noch eine Variable erstellen, in der lediglich die maskierte Variante steht. Zumal $username dann auch fachlich fraglich ist, weil es ja $escaped_username ist. sprintf() hat dann auch nicht ganz so viel Sinn. Besser:

    $query = sprintf("SELECT firstname, lastname FROM users WHERE usergroup = '%s'",
                 mysqli_real_escape_string($mysqli, $_POST['usergroup']));
    

    mysqli_set_charset() will nicht nur den Kodierungsnamen ohne Bindestrich haben, es will auch nur die im Handbuch festgelegten Namen haben. "iso-8859-1" ist zum Beispiel nicht gültig, auch nicht ohne Bindestrichen.

    Vor jeder Kommunikation zwischen Anwendung und Datenbank müssen alle Daten für die Datenbank aufbereitet werden.

    Nö, müssen sie nicht. Nur für das Einbetten in den Statement-String. Im DBMS stehen sie ja nicht aufbereitet drin, sondern ... ganz anders - wie auch immer das DBMS sie speichert. Dem würde auch widersprechen, dass sie bei Prepared Statements nicht "für die Datenbank" aufbereitet werden müssen.

    Die Schachtelung bei Fehleraufkommen müsste noch etwas sinnvoller gestaltet werden. Momentan ist das alles linear. Das lässt sich zwar besser unterbrechen, um Dinge zu erklären, aber im realen Leben kann man ja nicht (ungestraft) einfach weitermachen, wenn ein Verbindungsfehler oder einer bei einer vorhergehenden Funktion/Methode aufgetreten ist.

    try-catch kann seinen Vorteil auch viel besser ausspielen, wenn nicht jeder Fehler einzeln gefangen und behandelt wird, sondern wenn diese Behandlung am Ende steht. Muss natürlich je nach Sinnfälligkeit gegenüber dem Anwendungsfall betrachtet werden, aber im Allgemeinen reicht ein catch-Block am Ende des gesamten Vorgangs (oder mehrere, wenn unterschiedliche Exceptiontypen separat gefangen werden sollen).

    mysql_real_escape_string() kann zwar theoretisch einen Fehler zurückgeben, aber praktisch tritt das nicht auf, wenn man eine Verbindung geöffnet hat. Deswegen verwendet man das üblicherweise ohne Fehlerbehandlung.

    Änderungen dürfen niemals am Produktivsystem durchgeführt werden!

    Dürfen schon, verbietet ja kein Gesetz. Also "sollten" oder eine andere als Empfehlung formulierte Variante.

    dedlfix.

    1. problematische Seite

      Hallo dedlfix,

      auch Dir herzlichen Dank für Dein Feedback!

      Auch ich würde nicht "je nach Anwendungsfall" sondern "nach Vorliebe" nehmen, weil funktional sich mysqli und PDO nicht viel nehmen, jedenfalls nicht für die Anwendungsfälle der Zielgruppe. Für bestimmte, eher selten verwendete Dinge braucht man mysqlis auf MySQL zugeschnittene Funktionalität. PDO ist eher als einheitliche Schnittstelle für mehrere DBMS als für die Verwendung bei datenbankspezifischen Eigenheiten.

      Werde ich ändern.

      Eine Umstiegshilfe findet sich unten.

      Unten, oben, hier, dort ... sind alles keine gescheiten Linkbezeichnungen. "Informationen dazu in der Umstiegshilfe." wäre schon etwas besser.

      Hmm. Und das, wo ich mich immer über sowas aufrege. Darf natürlich nicht sein, wird geändert!

      Abkürzungen und Fachbegriffe sollte nochmal betrachtet werden, ob man da nicht noch anfängerfreundliche Kurzerklärungen/Übersetzungen hinzufügen kann. Ist ja nicht jedem geläufig, was zum Beispiel API heißt.

      Werde ich auch nochmal im gesamten Artikel drauf achten. Ich hab schon versucht, bei möglichst allen Vorkommen von sowas auf das Glossar zu verlinken (wo ich dann natürlich die fehlenden Einträge noch hinzufüge). Aber dann muss ich da wohl nochmal gucken. Meinst Du, das direkt im Artikel zu erklären ist besser als den Weg über das Glossar zu gehen?

      Maskieren und sprintf(): Ich würde da nicht noch eine Variable erstellen, in der lediglich die maskierte Variante steht. Zumal $username dann auch fachlich fraglich ist, weil es ja $escaped_username ist. sprintf() hat dann auch nicht ganz so viel Sinn. Besser:

      $query = sprintf("SELECT firstname, lastname FROM users WHERE usergroup = '%s'",
                   mysqli_real_escape_string($mysqli, $_POST['usergroup']));
      

      Ok, kann ich auch gerne so machen. So würde ich das normalerweise auch machen. Ich glaube ich wollte das einfach zu sehr „nach Lehrbuch“ und strukturiert machen, dass mir gar nicht mehr aufgefallen ist, dass man das so eigentlich gar nicht macht.

      mysqli_set_charset() will nicht nur den Kodierungsnamen ohne Bindestrich haben, es will auch nur die im Handbuch festgelegten Namen haben. "iso-8859-1" ist zum Beispiel nicht gültig, auch nicht ohne Bindestrichen.

      Den Hinweis füge ich mit ein.

      Vor jeder Kommunikation zwischen Anwendung und Datenbank müssen alle Daten für die Datenbank aufbereitet werden.

      Nö, müssen sie nicht. Nur für das Einbetten in den Statement-String. Im DBMS stehen sie ja nicht aufbereitet drin, sondern ... ganz anders - wie auch immer das DBMS sie speichert. Dem würde auch widersprechen, dass sie bei Prepared Statements nicht "für die Datenbank" aufbereitet werden müssen.

      Ja, ist richtig. Muss ich umformulieren. Das war dann doch wohl zuviel des Guten, wie ich immer wieder auf den Kontextwechsel aufmerksam machen wollte. Hatte Rolf ja auch schon angemerkt.

      Die Schachtelung bei Fehleraufkommen müsste noch etwas sinnvoller gestaltet werden. Momentan ist das alles linear. Das lässt sich zwar besser unterbrechen, um Dinge zu erklären, aber im realen Leben kann man ja nicht (ungestraft) einfach weitermachen, wenn ein Verbindungsfehler oder einer bei einer vorhergehenden Funktion/Methode aufgetreten ist.

      Hättest Du da einen Vorschlag? Ich wollte das halt so „offen“ wie möglich halten, da das ja tatsächlich davon abhängig ist, was man gerade vorhat. Sollte ich sonst evtl. weitere geplante Artikel hintenanstellen und erstmal ein Anfängertutorial mit ein paar konkreten Beispielen schreiben, auf das man dann verweisen kann? Ich denke, das könnte man in so einem Rahmen wahrscheinlich etwas besser erklären. Oder was meinst Du?

      try-catch kann seinen Vorteil auch viel besser ausspielen, wenn nicht jeder Fehler einzeln gefangen und behandelt wird, sondern wenn diese Behandlung am Ende steht. Muss natürlich je nach Sinnfälligkeit gegenüber dem Anwendungsfall betrachtet werden, aber im Allgemeinen reicht ein catch-Block am Ende des gesamten Vorgangs (oder mehrere, wenn unterschiedliche Exceptiontypen separat gefangen werden sollen).

      Ja, so verwende ich try-catch auch üblicherweise. Hier hatte ich auch tatsächlich zuerst nur einen try-catch-Block, hab es dann aber in zwei aufgeteilt. Ich habe mir dabei gedacht, dass so etwas deutlicher wird, dass bei einem Fehler beim Verbindungsaufbau sicherlich eine andere Fehlerbehandlung stattfindet als wenn eine Datenbankabfrage schief geht. Gleiches Problem wie zuvor, zu sehr in „Kategorie Lehrbuch“ gedacht? Also lieber nur einen Block verwenden?

      mysql_real_escape_string() kann zwar theoretisch einen Fehler zurückgeben, aber praktisch tritt das nicht auf, wenn man eine Verbindung geöffnet hat. Deswegen verwendet man das üblicherweise ohne Fehlerbehandlung.

      Hab ich selbst auch noch nie überprüft :-) Wohl ebenfalls das Problem, dass ich es zu gut gemeint habe. Kommt raus.

      Änderungen dürfen niemals am Produktivsystem durchgeführt werden!

      Dürfen schon, verbietet ja kein Gesetz. Also "sollten" oder eine andere als Empfehlung formulierte Variante.

      Ja, hört sich etwas übertrieben an ;-) Wird geändert.

      Vielen Dank und Gruß
      Dennis

      1. problematische Seite

        Tach!

        Abkürzungen und Fachbegriffe sollte nochmal betrachtet werden, ob man da nicht noch anfängerfreundliche Kurzerklärungen/Übersetzungen hinzufügen kann. Ist ja nicht jedem geläufig, was zum Beispiel API heißt.

        Werde ich auch nochmal im gesamten Artikel drauf achten. Ich hab schon versucht, bei möglichst allen Vorkommen von sowas auf das Glossar zu verlinken

        Das ist mir beim weiternen Lesen dann auch aufgefallen. Und ich habe auch nicht mehr so darauf geachtet, mehr auf inhaltliche Dinge. Eigentlich fiel mir nur API als noch erklärwürdig auf. Das muss man am Ende nochmal prüfen, wenn der Inhalt erstmal so gut wie fertig ist. Glossar-Verlinkungen sind auch nicht verkehrt. Wenn es für das Verständnis wichtig ist, sollte man jedoch lieber ein paar Worte an Ort und Stelle fallenlassen. Aber wie gesagt, erstmal der Inhalt.

        Die Schachtelung bei Fehleraufkommen müsste noch etwas sinnvoller gestaltet werden. Momentan ist das alles linear. Das lässt sich zwar besser unterbrechen, um Dinge zu erklären, aber im realen Leben kann man ja nicht (ungestraft) einfach weitermachen, wenn ein Verbindungsfehler oder einer bei einer vorhergehenden Funktion/Methode aufgetreten ist.

        Hättest Du da einen Vorschlag? Ich wollte das halt so „offen“ wie möglich halten, da das ja tatsächlich davon abhängig ist, was man gerade vorhat. Sollte ich sonst evtl. weitere geplante Artikel hintenanstellen und erstmal ein Anfängertutorial mit ein paar konkreten Beispielen schreiben, auf das man dann verweisen kann? Ich denke, das könnte man in so einem Rahmen wahrscheinlich etwas besser erklären. Oder was meinst Du?

        Da muss ich nochmal genauer überlegen. Einserseits kann man die Beispiele als zusammengestellte Code-Stücke betrachten, zwischen denen eigentlich noch anderer Code der Anwendung zu liegen kommt. Die Verbindung wird ja nicht für jedes Statement separat geöffnet (sollte sie jedenfalls nicht). Andererseits sollt man schon eine vollständige und sinnvolle Vorgehensweise zeigen. Das bläht sich dann ganz schnell auf, aber in der Praxis ist das ja nicht anders.

        try-catch kann seinen Vorteil auch viel besser ausspielen, wenn nicht jeder Fehler einzeln gefangen und behandelt wird, sondern wenn diese Behandlung am Ende steht.

        Ja, so verwende ich try-catch auch üblicherweise. Hier hatte ich auch tatsächlich zuerst nur einen try-catch-Block, hab es dann aber in zwei aufgeteilt. Ich habe mir dabei gedacht, dass so etwas deutlicher wird, dass bei einem Fehler beim Verbindungsaufbau sicherlich eine andere Fehlerbehandlung stattfindet als wenn eine Datenbankabfrage schief geht. Gleiches Problem wie zuvor, zu sehr in „Kategorie Lehrbuch“ gedacht? Also lieber nur einen Block verwenden?

        "Ordentliche" Systeme haben unterschiedliche Exceptiontypen, so dass man Verbindungsfehler und Statement-Fehler getrennt behandeln kann. Ich denke, für das Beispiel tut es auch ein einzelner Block für alles. Eine universelle Lösung für alle Anwendungsfälle wird es eh nicht geben.

        Wir haben hier quasi das Bittersmann-Riesterer-Problem. Einerseits korrekt machen, andererseits didaktisch sinnvoll aufbereiten. Es soll schon best practice zeigen, es kann aber nicht für jeden eine kopierfähge Vorlage bieten.

        dedlfix.

        1. problematische Seite

          Hallo dedlfix,

          nochmal danke für die Antwort. Ich überlege bis morgen nochmal und mache dann einfach schon mal weiter (genug Input habe ich von Euch ja erstmal bekommen :-) ). Vielleicht findet man ja noch eine schöne Lösung. Und sonst evtl. wirklich noch ein zweiter Artikel mit etwas anderem Fokus.

          Wir haben hier quasi das Bittersmann-Riesterer-Problem

          Schön ausgedrückt ;-) Bin mal gespannt wie lang das dauert, bis es zum geflügelten Wort wird und einen eigenen Wikiartikel bekommt :-)

          Gruß
          Dennis

        2. problematische Seite

          Tach!

          Die Schachtelung bei Fehleraufkommen müsste noch etwas sinnvoller gestaltet werden. Momentan ist das alles linear. Das lässt sich zwar besser unterbrechen, um Dinge zu erklären, aber im realen Leben kann man ja nicht (ungestraft) einfach weitermachen, wenn ein Verbindungsfehler oder einer bei einer vorhergehenden Funktion/Methode aufgetreten ist.

          Hättest Du da einen Vorschlag?

          Da muss ich nochmal genauer überlegen.

          Ich denke nun, dass wir da den Anwendungsfall einer kleinen Seite, die genau eine Datenbankabfrage macht, zugrundelegen können.

          Eigentlich wäre mir auch wichtig, dass die Fehlerbehandlung sich nicht darauf beschränkt, die Meldung an den Seitenbesucher auszugeben, sondern irgendwas macht, was dem Besucher trotzdem einen Nutzen bringt. Das kann man zwar aufgrund der vielfältigen Real-World-Anforderungen nicht wirklich in Tutorial-Code gießen, es sei denn, man überlegt sich ein komplettes Szenario. Aber vielleicht kann man den Kommentar im Fehlerbehandlungsblock so formulieren, dass die Fehlermeldung ins Logfile oder dergleichen soll und der Besucher höchstens eine Tröstmeldung ohne technische Details zu sehen bekommt, besser noch eine möglichst nützliche Alternative.

          dedlfix.

          1. problematische Seite

            Hallo dedlfix,

            Hättest Du da einen Vorschlag?

            Da muss ich nochmal genauer überlegen.

            Ich denke nun, dass wir da den Anwendungsfall einer kleinen Seite, die genau eine Datenbankabfrage macht, zugrundelegen können.

            ja, das ginge sicherlich.

            Eigentlich wäre mir auch wichtig, dass die Fehlerbehandlung sich nicht darauf beschränkt, die Meldung an den Seitenbesucher auszugeben, sondern irgendwas macht, was dem Besucher trotzdem einen Nutzen bringt.

            Klar, wäre wünschenswert.

            Das kann man zwar aufgrund der vielfältigen Real-World-Anforderungen nicht wirklich in Tutorial-Code gießen, es sei denn, man überlegt sich ein komplettes Szenario. Aber vielleicht kann man den Kommentar im Fehlerbehandlungsblock so formulieren, dass die Fehlermeldung ins Logfile oder dergleichen soll und der Besucher höchstens eine Tröstmeldung ohne technische Details zu sehen bekommt, besser noch eine möglichst nützliche Alternative.

            Ich denke mittlerweile, ein komplettes Szenario wäre die beste Alternative. Eigentlich kann man Fehlerbehandlung nur so halbwegs sinnvoll verdeutlichen. Das komplette Szenario würde aber den Rahmen des Artikels sprengen, das müsste da ja mehrere Male drin vorkommen. Mein Vorschlag wäre, wie schon zuvor gesagt, da einen Anfängerartikel „vorzuschalten“, welches ein komplettes Szenario durchspielt. Darauf würde man dann aus dem Artikel heraus immer wieder verweisen. Oder ist das zu kurz gedacht?

            Was meinst Du? Was meinen die anderen?

            Unabhängig davon wäre es natürlich kein Problem, die Kommentare in dem Artikel auszubauen und die von Dir genannten Punkte da unterzubringen.

            Ansonsten fange ich jetzt an, erstmal alles andere Feedback einzubauen und hebe mir die Baustelle mal bis zum Ende auf.

            Gruß
            Dennis

  4. problematische Seite

    hi,

    Über Feedback würde ich mich freuen.

    Nur ne Idee, eine DB-Verbindung im Rahmen einer Factory aufzubauen. Bei mir sieht das so aus:

    my $dbh = $self->dbh( 
      base    => 'webdaten',
      charset => 'utf-8'
    );
    

    Also dass ein einfacher Methodenaufruf einen Data-Base-Handler liefert. Übergeben wird lediglich der Name der Datenbank und ggf. die gewünschte Zeichenkodierung und um alles Andere kümmert sich die ausgelagerte Methode dbh() die ich in PHP pdo() nennen würde. Diese Methode weiß natürlich auch wo die Credentials zu finden sind -- und somit sind die auch gleich zentral hinterlegt.

    Noch abstrakter liefert eine aufgerufene Methode gleich die Daten so dass ein PDO oder gar SQL im eigenen Code gar nicht mehr auftaucht.

    Und dann gäbe es noch die Möglichkeit, DB-Geschichten in eigene Klassen auszulagern, z.B. sowas in der Art:

    my $shop = Shop::Order->new( base => 'outlets' );
    $shop->save_order( $self->{SESSION}{Cart} );
    
    --
    Hello World! Jeder fängt mal klein an ;)
    1. problematische Seite

      Hallo pl,

      auch Dir danke für Dein Feedback.

      Über Feedback würde ich mich freuen.

      [Factory Pattern] [Konfiguration] [DBH] [OOP] [ORM]

      Im Prinzip ist das richtig, dass man das im Allgemeinen und insbesondere bei größeren Projekten so macht. Darüber hatten wir hier auch an anderer Stelle schon gesprochen. Das geht aber in diesem Fall am Thema vorbei, da hier die drei von PHP bereitgestellten APIs vorgestellt werden sollen und nicht irgendetwas, was man sonst noch so machen könnte. Diese Themen sind aber evtl. Gegenstand eines Fortgeschrittenen-Tutorials, sofern wir uns dazu entscheiden, eins zu schreiben.

      Gruß
      Dennis

  5. problematische Seite

    Hallo Tagwächter, hallo Rolf b, hallo dedlfix, hallo zusammen, :-)

    danke nochmal für Euer Feedback! Den Großteil davon habe ich jetzt (hoffentlich) eingearbeitet. Ich hoffe, dass ich nichts vergessen oder übersehen habe. Sagt sonst bitte einfach Bescheid. Ich habe jetzt folgendes geändert:

    • error, errno, affected_rows und num_rows hinzugefügt (Tagwächter)
    • Definition API (dedlfix)
    • Definition/Links unbekannte Begriffe (dedlfix)
    • Auswahl API nach Anwendungsfall => Auswahl API nach persönlicher Vorliebe (Rolf b, dedlfix)
    • Falsche Verwendung mysqli_connect_error()/mysqli_connect_errno() (Rolf b)
    • MySQL wurde aus Sicherheitsgründen entfernt streichen (Rolf b, dedlfix)
    • Kein Kontextwechsel bei PDO (Rolf b, dedlfix)
    • Änderung am Produktivsystem als Empfehlung (dedlfix)
    • "oben, unten, links, rechts", sinnvolle Linknamen (dedlfix)
    • Hinweis zu erlaubten Zeichensätzen (dedlfix)
    • Nur ein try...catch-Block (dedlfix)
    • Keine Fehlerüberprüfung bei mysql_real_escape_string (dedlfix)
    • Keine Variable für Query, direkte Anwendung von escape_string (dedlfix)

    @Rolf b, Du schriebst:

    Und um zu prüfen, ob $link = mysqli_connect(...) fehlschlug, soll man if (!$link) testen. (siehe Beispiel hier)

    Ich bin mir da etwas unschlüssig. Wenn ich das Manual richtig verstehe, müssten doch diese drei Varianten auf's gleiche hinauslaufen?

    $link = mysqli_connect(...);
    
    if (!$link) { /* ... */ }
    if (mysqli_connect_error()) { /* ... */ }
    if (mysqli_connect_errno()) { /* ... */ }
    

    Oder irre ich mich da? Wenn nicht, gibt es eine Variante, die zu bevorzugen ist? Das einzige was ich gelesen habe ist, dass $link->connect_error erst ab PHP 5.3 funktioniert und man stattdessen die prozedurale Variante nehmen muss. Das ist aber eine Anmerkung, die man sich hier meiner Meinung nach sparen kann. Oder was meint ihr?

    Was sonst noch offen wäre ist die Fehlerbehandlung, da bin ich mir weiterhin unschlüssig, was die beste Variante ist. Man könnte

    • es so lassen wie es ist, ein Anfängertutorial mit konkretem Anwendungsfall erstellen und darauf verlinken
    • einen konkreten Anwendungsfall in diesem Artikel unterbringen
    • die Fehlerbehandlung in diesem Artikel irgendwie sinnvoll verschachteln oder
    • die Kommentare innerhalb der Fehlerbehandlung ausbauen und sonst nichts ändern

    Sicherlich gibt es auch noch mehr Möglichkeiten. Was meint ihr dazu?

    Weiteres Feedback ist natürlich weiterhin erwünscht :-)

    Gruß
    Dennis

    1. problematische Seite

      Hallo Dennis,

      die Version if (!$link) steht so in php.net und daher würde ich das für die bevorzugte Methode halten. Vor allem deshalb, weil es keinen API-Call erfordert. Der Hinweis, dass $link im Fehlerfall FALSE ist, wäre mMn relevant.

      Die Abfrage auf $link->connect_errno sieht nach der idiomatisch richtigen Formulierung für mysqli/oo aus, zumindest wird es so im mysqli Quickstart auf php.net gemacht.

      Den Hinweis auf connect_error und PHP 5.2.9 bzw. 5.3.0 würde ich mir verkneifen, ja. Diese Versionen sind aus dem Sommer 2009 und sie setzt hoffentlich niemand mehr ein.

      Rolf

      1. problematische Seite

        Hallo Rolf,

        die Version if (!$link) steht so in php.net und daher würde ich das für die bevorzugte Methode halten. Vor allem deshalb, weil es keinen API-Call erfordert. Der Hinweis, dass $link im Fehlerfall FALSE ist, wäre mMn relevant.

        Die Abfrage auf $link->connect_errno sieht nach der idiomatisch richtigen Formulierung für mysqli/oo aus, zumindest wird es so im mysqli Quickstart auf php.net gemacht.

        Den Hinweis auf connect_error und PHP 5.2.9 bzw. 5.3.0 würde ich mir verkneifen, ja. Diese Versionen sind aus dem Sommer 2009 und sie setzt hoffentlich niemand mehr ein.

        besten Dank! Dann werde ich das so machen.

        Gruß
        Dennis

  6. problematische Seite

    Moin!

    Ich habe mal gelesen, dass aufgrund der Konzeption (Escaping vs. Trennung von Daten und Anweisungen) nicht mal mysqli_real_escape_string richtig angewendet absolute Sicherheit gegen SQL-Injections bietet, sondern dies nur Prepared Statements vermögen – es ging aber wohl nicht um eine konkrete Lücke sondern eher darum, dass nicht eindeutig zu beweisen ist, dass mysqli_real_escape_string absolut sicher ist.

    Dummerweise finde ich die Quelle nicht wieder (Stackoverflow?)...

    Grüße

    1. problematische Seite

      Dummerweise finde ich die Quelle nicht wieder (Stackoverflow?)...

      php.net selbst warnt:

      Achtung Security: the default character set

      The character set must be set either at the server level, or with the API function mysqli_set_charset() for it to affect mysqli_real_escape_string(). See the concepts section on character sets for more information.

      soll also heißen, wenn die Zeichenkodierung nicht korrekt gesetzt ist, dann kann das zu Problem führen. Da mysqli_real_escape_string() aber nicht abbricht wenn die Zeichenkodierung nicht oder nicht korrekt gesetzt ist (letztes kann nicht wirklich geprüft werden) ist es eben nach Ansicht der PHP-Entwickler nicht sicher.

      1. problematische Seite

        Das ist ja auch der Grund, warum mysql_escape_string durch mysql_real_escape_string ersetzt (im Sinne von Empfehlung, das zu verwenden) wurde:
        Es hat wild drauf los escaped, weil ihm die Zeichenkodierung der Datenbank herzlich egal war. Das neuere will die benutzte DB-Verbindung wissen (mysqli_escape_string ebenfalls), aber da haben wir den Salat, den du schildertest.

        Richtige Anwendung beinhaltet die Beachtung des Zeichensatzes.

        1. problematische Seite

          Tach!

          Das ist ja auch der Grund, warum mysql_escape_string durch mysql_real_escape_string ersetzt (im Sinne von Empfehlung, das zu verwenden) wurde:
          Es hat wild drauf los escaped, weil ihm die Zeichenkodierung der Datenbank herzlich egal war. Das neuere will die benutzte DB-Verbindung wissen (mysqli_escape_string ebenfalls), aber da haben wir den Salat, den du schildertest.

          Es kann sein, dass mysql_escape_string() aus der Zeit vor dem Einzug der Beachtung der Zeichenkodierung stammt. Erst mit Version 4.5 (oder war es 4.1?) konnte man die verwendete Zeichenkodierung einstellen und auch Unicode wurde erst ab dem Zeitpunkt beachtet. Davor war die Kodierungseinstellung lediglich ein serverseitiger Parameter.

          Richtige Anwendung beinhaltet die Beachtung des Zeichensatzes.

          Es gibt mindestens eine asiatische Zeichenkodierung, bei der Bytes aus dem Bereich 00-7f in Kombination mit anderen Bytes ein bestimmtes Zeichen ergeben. Es kann dann zu Fehlfunktionen kommen, wenn man gemäß dieser Kodierung maskiert, aber der Server was anderes erwartet, und dann syntaktisch wichtige Zeichen erkennt, die eigentlich Nutzdaten sind. Ein konkretes Szenario ist mir noch nicht zufällig über den Weg gelaufen. Solch ein Szenario spielt aber keine Rolle, wenn Server und Maskierfunktionen ASCII-basierte Kodierungen annehmen. Alle zu maskierenden Zeichen liegen im ASCII-Bereich, und selbst addslashes() schafft es, die wirklich wichtigen davon zu berücksichtigen. Die unwichtigen beeinflussen nicht die Interpretation als Statement, sondern sind nur für Logfiles von Interesse.

          Also theoretisch gibt es da Probleme, wenn man Fehler macht, hierzulande ist das aber kaum sicherheitstechnisch relevant, weil hier wohl eher keine nicht auf ASCII basierende Zeichkodierungen in den MySQL-Servern eingestellt sein werden.

          dedlfix.

          1. problematische Seite

            php.net schreibt:

            Characters encoded are NUL (ASCII 0), \n, \r, , ', ", and Control-Z.

            Die folgende Query erwartet einen numerischen Parameter (als PHP-String mit string parsing):

               $sql = "select foo,bar from atable where key=$keyValue"
            

            Wenn ich es schaffe, hier statt bspw. 4711 den "Wert" 1 OR 1=1 zu injizieren, hilft mir Escaping jeglicher Art nicht weiter. Oder schlimmer noch: 1; DROP atable. Das Semikolon wird nicht escaped.

            Wenn der Variableninhalt, der in die Query eingesetzt wird, im SQL String in Anführungszeichen gesetzt wird, bin ich mit Escaping vermutlich sicher, weil ich dann nicht mehr aus dem String hinauskomme. Ob spezielle Multibyte-Zeichensätze trotzdem ein Schlupfloch aus dem String hinaus ermöglichen, weiß ich nicht.

            Trotzdem ist SQL mit direkt eingesetzten Werten ein Kopfschmerzgenerator und daher würde ich dann, wenn zugelieferte Werte als Parameter zu nutzen sind, prepared statements immer vorziehen, auch wenn das einen zusätzlichen Roundtrip zum SQL Server bedeutet. Wenn man Hochlast-Sites baut, in denen das zum Problem werden kann, muss man ohnehin ganz andere Mechanismen zur Laststeuerung bzw. -reduktion einsetzen.

            Rolf

            1. problematische Seite

              Hallo

              Characters encoded are NUL (ASCII 0), \n, \r, , ', ", and Control-Z.

              Die folgende Query erwartet einen numerischen Parameter (als PHP-String mit string parsing):

              Da ist schon der Denkfehler. Warum sollte man Zahlen („numerischer Parameter“) mit einer Stringfunktion (mysqli_real_escape_string) behandeln?

                 $sql = "select foo,bar from atable where key=$keyValue"
              

              Behandle die Variable ihrem Typ entsprechend …

                 $sql = "select foo,bar from atable where key= " . intval($keyValue); // ich nehme eine Ganzzahl an
              

              … und dieses Problem löst sich in Luft auf.

              mysqli_real_escape_string ist keine Kanone, die Splittergranaten verschießt, die alles treffen (auch Spatzen). Es ist ein Scharfschützengewehr, mit dem man auf Zeichenketten schießt (nur Spatzen).

              Tschö, Auge

              --
              Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
              Wolfgang Schneidewind *prust*
            2. problematische Seite

              Tach!

              php.net schreibt:

              Characters encoded are NUL (ASCII 0), \n, \r, , ', ", and Control-Z.

              Die folgende Query erwartet einen numerischen Parameter (als PHP-String mit string parsing):

                 $sql = "select foo,bar from atable where key=$keyValue"
              

              Wenn ich es schaffe, hier statt bspw. 4711 den "Wert" 1 OR 1=1 zu injizieren, hilft mir Escaping jeglicher Art nicht weiter.

              Wenn du da Escaping versuchst, hast du das System nicht verstanden. Escaping ist kein magisches "Mach-es-in-jedem-Fall-sicher-Ding". Die Funktion bei MySQL heißt ja auch nicht umsonst _string am Ende.

              Im Kontextwechsel-Artikel gibt es jedenfalls nicht umsonst einen eigenen Abschnitt für Zahlen.

              Oder schlimmer noch: 1; DROP atable. Das Semikolon wird nicht escaped.

              Mehr als ein Statement führt MySQL nicht aus, wenn man nicht Multi-Query händisch aktiviert hat.

              Trotzdem ist SQL mit direkt eingesetzten Werten ein Kopfschmerzgenerator und daher würde ich dann, wenn zugelieferte Werte als Parameter zu nutzen sind, prepared statements immer vorziehen, auch wenn das einen zusätzlichen Roundtrip zum SQL Server bedeutet. Wenn man Hochlast-Sites baut, in denen das zum Problem werden kann, muss man ohnehin ganz andere Mechanismen zur Laststeuerung bzw. -reduktion einsetzen.

              Wenn du dabei schon Kopfschmerzen bekommst, solltest du vielleicht nicht programmieren. Du kannst zwar im Falle SQLs mit Prepared Statements den Kontextwechsel und die Maskiernotwendigkeit umgehen, aber du brauchst das Prinzip noch zu jeder Menge anderer Gelegenheiten, für die es etwas vergleichbares nicht gibt. Du musst dich also weiterhin damit beschäftigen, an welcher Stelle welches Escaping notwendig ist. Wenn du das Prinzip verstanden hast, spielt es im Prinzip keine Rolle, ob du korrektes Escaping oder Prepared Statements verwendest.

              dedlfix.

  7. problematische Seite

    Hallo zusammen,

    der Artikel sollte jetzt vorerst fertig sein.

    Im Abschnitt APIs habe ich in Anlehnung an @dedlfix Vorschlag noch einen kleinen Absatz zur Fehlerbehandlung geschrieben. Darauf verweise ich dann am Ende jedes Beispiels.

    Den Vorschlag von @Rolf b, zumindest darauf hinzuweisen, dass MySQLi auch Prepared Statements anbietet, habe ich ebenfalls mit aufgenommen und gebe am Ende der Kapitel jeweils eine Empfehlung.

    Die fehlenden Glossar-Einträge werde ich noch nachziehen.

    Könnte bitte jemand mit entsprechenden Rechten den Artikel nach „PHP/Anwendung und Praxis/PHP MySQL API“ verschieben? Ich kann das leider nicht, da das mit dem Sperrbegriff kollidiert.

    Ansonsten ist der Artikel jetzt zum Abschuss freigegeben. Tobt Euch gerne aus, wenn ihr weiteres Verbesserungspotenzial seht. Das ist schließlich ein Wiki, das davon lebt, das viele mitmachen und die Artikel nach und nach verbessert werden. Da ist nichts in Stein gemeißelt ;-) In diesem Zusammenhang auch nochmal recht herzlichen Dank an alle, die hier äußerst konstruktive Kritik geäußert, den Artikel zumindest gelesen oder sonst wie geholfen haben. Das ist extrem hilfreich und erleichtert einem das Artikelschreiben ungemein. So würde ich mir das immer wünschen! Danke!

    Gruß
    Dennis

    1. problematische Seite

      Tach!

      Könnte bitte jemand mit entsprechenden Rechten den Artikel nach „PHP/Anwendung und Praxis/PHP MySQL API“ verschieben? Ich kann das leider nicht, da das mit dem Sperrbegriff kollidiert.

      Ist verschoben. Ein paar kleine Formulierungesänderungen werde ich noch einbauen. Du hast da den Punkt vielleicht nur übersehen, dass das Aufbereitung nicht für die Datenbank, sondern für den SQL-Statement-String notwendig ist.

      dedlfix.

      1. problematische Seite

        Hallo dedlfix,

        Ist verschoben.

        danke.

        Ein paar kleine Formulierungesänderungen werde ich noch einbauen.

        Sehr gerne.

        Du hast da den Punkt vielleicht nur übersehen, dass das Aufbereitung nicht für die Datenbank, sondern für den SQL-Statement-String notwendig ist.

        Ja, das habe ich offensichtlich übersehen. Hab's auf jeden Fall nicht mutwillig übergangen :-) Kann ich sonst auch gerne heute Abend überarbeiten.

        Gruß
        Dennis