Jan Wa: PHP - Umstellung auf mysqli

Hallo!

Ich stelle alte PHP-Skripte auf mysqli um. Dabei kommen mir Abfragen unter, die so aussehen:

$sqlStatement = "SELECT MAX(id) AS maxActiveNewsId FROM news";
$rs = mysql_fetch_array(mysql_query($sqlStatement));
return $rs['maxActiveNewsId'];

Ich konnte bisher also "mysql_fetch_array" und "mysql_query" in einer Zeile zusammenfassen.

Da ich nicht sehe, ob es diese Möglichkeit auch weiterhin mit mysqli gibt, wollte ich hier mal nachfragen.

Ich nutze den objektorientieren Stil beim Einsatz von mysqli und habe da jetzt am Ende eine Zeile mehr zu schreiben

$sqlStatement = "SELECT MAX(id) AS maxActiveNewsId FROM news";
$rs = $mysqli->query($sqlStatement);
$row = $rs->fetch_array(MYSQL_ASSOC);
return $row['maxActiveNewsId'];

Vielen Dank Jan

  1. Tach!

    $rs = mysql_fetch_array(mysql_query($sqlStatement));
    

    Ich konnte bisher also "mysql_fetch_array" und "mysql_query" in einer Zeile zusammenfassen.

    Da ich nicht sehe, ob es diese Möglichkeit auch weiterhin mit mysqli gibt, wollte ich hier mal nachfragen.

    Die gibt es, wenn du im Handbuch nach dem Procedural Style schaust. Aber ...

    Ich nutze den objektorientieren Stil beim Einsatz von mysqli und habe da jetzt am Ende eine Zeile mehr zu schreiben

    Wenn du es richtig und robust schreiben wolltest, hättest du noch weit mehr Zeilen zu schreiben. Du hast da keinerlei Reaktion auf Fehlerzustände im Code. Fehler treten nicht nur durch fehlerhafte SQL-Statements auf, denen man mit genügend Tests zur Entwicklungszeit bekommen könnte, sondern auch zur Laufzeit in der Form, dass das DBMS irgendwelche andere Probleme hat. Dein Script klatscht in dem Fall in die Hände, weil der Rückgabewert von mysql(i)_query() im Fehlerfall false liefert und das kein gültiger Wert für die Fetch-Funktion ist. Oder bei objektorientiertem Stil ist das kein Result-Objekt, an dem man Methoden aufrufen könnte.

    dedlfix.

  2. Hallo Jan,

    wenn Du unbedingt auf Errorhandling verzichten willst, geht's auch so:

    $sqlStatement = "SELECT MAX(id) AS maxActiveNewsId FROM news";
    $row = $mysqli->query($sqlStatement)->fetch_array(MYSQL_ASSOC)
    return $row['maxActiveNewsId'];
    

    Es gibt aber Verbesserungspotential.

    • Verwende fetch_assoc - fetch_array(MYSQL_ASSOC) ist ein umständlicherer Weg zum gleichen Ziel
    • Schreibe Dir eine Klasse, die die SQL Zugriffe technisch bündelt. Falls mysqli irgendwann auch mal deprecated sein sollte, brauchst Du nur dort umzustellen. Diese Klasse kennt dann Methoden wie "GetSingleValue", "GetSingleRow", "EnumerateResult". EnumerateResult bietet Dir die Change, mit Generatoren zu spielen :). Inserts und Updates sind etwas aufwändiger...
    • In der technischen Klasse kümmerst Du Dich um Freigabe von Ressourcen (z.B. free_result()) und korrektes Fehlerhandling. Das stumpfe "false", dass Du von mysqli->query() zurückbekommst, kannst Du dann gleich um mysqli->error anreichern.
    • Was man dann noch machen kann: Schreibe Dir Klassen, die die SQL Zugriffe nach fachlicher Domäne bündeln (Repositories) und die auf die technische Klasse zurückgreifen. D.h. du hast dann eine Klasse "NewsRepository" mit einer Methode "GetMaxActiveNewsId()". Dann hast Du (a) das SQL nicht durch die ganze Anwendung verbröselt und (b) kannst Du ein Fake-Repository verwenden wenn Du Unit-Tests ohne Datenbank machst.

    Rolf