Pit: mysqli: Umstellungsfehler

Hallo,

bei der Umstellung eines Scriptes von mysql_ auf mysqli komme ich einem Fehler nicht auf die Schliche. Das Script ist ein Addon zu fpdf, das eine Liste auf einem PDF generieren soll.

Könnt Ihr mal einen Blick auf meine Umstellung werfen? Es sind insgesamt 10 umgestellte Passagen von mysql_ auf mysqli.

Da müßte irgendwo (mindestens) ein Fehler drin sein, denn ich erhalte zwar ein PDF, aber kein Ergebnis innerhalb der zu generierenden Liste.

Pit

// 1:
while($data=mysql_fetch_row($this->results)) {
while($data=mysqli_fetch_row($this->results)) {
//------------------------------------------------------------

//2:
function query($query){
	$this->results = mysql_query($query,$this->conn);
	$this->numFields = mysql_num_fields($this->results);
	$this->results = mysqli_query($this->conn,$query);
	$this->numFields = mysqli_num_fields($this->results);
}
//------------------------------------------------------------

//3:
$stringWidth = $this->getstringwidth(mysql_field_name($this->results,$i)) + 6 ;
$stringWidth = $this->getstringwidth(mysqli_fetch_field_direct($this->$result, $i)->name) + 6;
//------------------------------------------------------------

//4:
$this->colTitles[$i] = mysql_field_name($this->results,$i) ;
switch (mysql_field_type($this->results,$i)){
$this->colTitles[$i] = mysqli_fetch_field_direct($this->$result, $i)->name ;
switch (mysqli_fetch_field_direct($this->$result, $i)->type){
//------------------------------------------------------------

//5:
while($row=mysql_fetch_row($this->results)){
while($row=mysqli_fetch_row($this->results)){
//------------------------------------------------------------

//6:
if(strlen(mysql_field_name($this->results,$i))>$flength){
$flength = strlen(mysql_field_name($this->results,$i));
if(strlen(mysqli_fetch_field_direct($this->$result, $i)->name)>$flength){
$flength = strlen(mysqli_fetch_field_direct($this->$result, $i)->name);
//------------------------------------------------------------

//7:
mysql_field_name($this->results,$i),
mysql_field_type($this->results,$i),
mysqli_fetch_field_direct($this->$result, $i)->name,
mysqli_fetch_field_direct($this->$result, $i)->type,
//------------------------------------------------------------

//8:
print $this->tablewidths[$i].", /* ".mysql_field_name($this->results,$i)." */\n\t\t":
print $this->tablewidths[$i]." /* ".mysql_field_name($this->results,$i)." */\n\t\t";
print $this->tablewidths[$i].", /* ".mysqli_fetch_field_direct($this->$result, $i)->name." */\n\t\t":
print $this->tablewidths[$i]." /* ".mysqli_fetch_field_direct($this->$result, $i)->name." */\n\t\t";
//------------------------------------------------------------

//9:
$this->colTitles[$i] = mysql_field_name($this->results,$i) ;
switch (mysql_field_type($this->results,$i)){
$this->colTitles[$i] = mysqli_fetch_field_direct($this->$result, $i)->name ;
switch (mysqli_fetch_field_direct($this->$result, $i)->type){
//------------------------------------------------------------

//10:
mysql_data_seek($this->results,0);
mysqli_data_seek($this->results,0);
  1. Hallo

    bei der Umstellung eines Scriptes von mysql_ auf mysqli komme ich einem Fehler nicht auf die Schliche.

    Du solltest mindestens die Schreibung prüfen. Du benutzt an einigen Stellen $this->$result an anderen Stellen $this->$results.

    Tschö, Auge

    --
    Eine Kerze stand [auf dem Abort] bereit, und der Almanach des vergangenen Jahres hing an einer Schnur. Die Herausgeber kannten ihre Leser und druckten den Almanach auf weiches, dünnes Papier.
    Kleine freie Männer von Terry Pratchett
    1. Tach!

      Ergänzung:

      Du solltest mindestens die Schreibung prüfen. Du benutzt an einigen Stellen $this->$result an anderen Stellen $this->$results.

      Wenn es wirklich dieser eine Buchstabe sein sollte, dann sollte es dazu Notice-Meldungen geben, beim Versuch auf eine nicht vorhandene Eigenschaft zuzugreifen. Vorausgesetzt das error_reporting ist auf E_ALL eingestellt. Und das sollte beim Entwickeln immer der Fall sein, schon allein, um Tippfehler dieser Art zu finden.

      dedlfix.

    2. Hallo Auge,

      wenn die mysql-Version an $this->results zuweist und die mysqli-Version an $this->result, dürfte das ein klarer Kandidat sein.

      Rolf

      --
      sumpsi - posui - clusi
      1. Hallo

        wenn die mysql-Version an $this->results zuweist und die mysqli-Version an $this->result, dürfte das ein klarer Kandidat sein.

        Nicht nur das. Im gezeigten Code werden result und results auch in deN MySQLi-Anweisungen vermischt. Irgendwie riecht mir das nach einem Schreibfehler. Ob eine von dedlfix angemerkte Meldung über die Verwendung einer nicht vorhandenen Eigenschaft angezeigt wird, hängt ja, wie er selbst schrieb, vom eingestellten Level des Reportings ab.

        Dazu sollte sich Pit mal äußern.

        Tschö, Auge

        --
        Eine Kerze stand [auf dem Abort] bereit, und der Almanach des vergangenen Jahres hing an einer Schnur. Die Herausgeber kannten ihre Leser und druckten den Almanach auf weiches, dünnes Papier.
        Kleine freie Männer von Terry Pratchett
    3. Hallo (Adler)Auge, 😉

      Du solltest mindestens die Schreibung prüfen. Du benutzt an einigen Stellen $this->$result an anderen Stellen $this->$results.

      Ja, daran lag es! Vielen Dank für Deinen scharfen Blick.

      "Nomen est omen", wie man so schön sagt, hm? 😀

      Pit

      P.S: dedlfix Anmerkung zum Notice im Errorlog habe ich aufgenommen.

      1. Hallo

        Du solltest mindestens die Schreibung prüfen.

        Ja, daran lag es!

        Schön.

        P.S: dedlfix Anmerkung zum Notice im Errorlog habe ich aufgenommen.

        Nimm ihn nicht nur auf, sondern auch ernst. Während der Entwicklung gehört der folgende Block an den Anfang eines jedes Skripts, das nicht (ausschließlich) von anderen Skripten mit require(), include() oder deren _once-Varianten eingebunden wird.

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

        Tschö, Auge

        --
        Eine Kerze stand [auf dem Abort] bereit, und der Almanach des vergangenen Jahres hing an einer Schnur. Die Herausgeber kannten ihre Leser und druckten den Almanach auf weiches, dünnes Papier.
        Kleine freie Männer von Terry Pratchett
  2. Tach!

    Könnt Ihr mal einen Blick auf meine Umstellung werfen?

    Da müßte irgendwo (mindestens) ein Fehler drin sein, denn ich erhalte zwar ein PDF, aber kein Ergebnis innerhalb der zu generierenden Liste.

    Debugging gehört zum Programmieren, auch wenn es eine eher unangenehme Tätigkeit dabei ist. Aufgabe des Debugging ist, die Stelle zu finden, an der der Code sich anders verhält als erwartet. Kontrollausgaben mit var_dump() sind eine einfache Möglichkeit dafür. An welcher Stelle des Codes also erhältst du ein anderes Ergebnis als du erwartest? Das herauszufinden ist die erste Maßnahme, wenn auf den Code zu schauen nichts ergibt.

    dedlfix.

    1. Hallo dedlfix,

      Forum Debugging ist doch eine beliebte Methode. Und oft genug auch erfolgreich genug.

      Vermutlich mindestens so erfolgreich wie die klassische Methode des Organic Debugging.

      Aus dem (zurückgewiesenen) Eintrag des „The New Hacker's Dictionary“ (fett von mir):

      Reportedly, the output from a compilation or assembly of the suspect program is placed on the floor, with a large flat dish on top of it, and an indoor plant in a pot is placed in the centre of the dish. The dish is then filled with water. The principle is that any bugs in the program will be attracted towards the house plant and drown as they try to cross the intervening water. From statistical evidence this seems about as effective a technique as many others currently in use.

      Die Terminologie zeigt das Alter des Begriffs, er dürfte aus den 60ern stammen 😂

      Rolf

      --
      sumpsi - posui - clusi
  3. Hallo Pit,

    Bei Konstrukten wie solchen reagiere ich automatisch allergisch:

    $this->colTitles[$i] = mysqli_fetch_field_direct($this->$result, $i)->name ;
    switch (mysqli_fetch_field_direct($this->$result, $i)->type){
    

    Sowas sollte man cachen:

    $feldInfo = mysqli_fetch_field_direct($this->$result, $i);
    $this->colTitles[$i] = $feldInfo->name;
    switch ($feldInfo->type){
    

    Es ist aber auch nicht optimal. Man weiß nicht, inwieweit der mysqli-Treiber diese Informationen puffert, es gibt eine "Sammel-Funktion" dafür:

    Entweder: $finfo = $result->fetch_fields();
    Oder: $finfo = mysqli_fetch_fields($result);

    Dann hat man die Field-Infos in einem Array und kann das Array verarbeiten, statt für jedes Feld neu zur DB zu rennen.

    Rolf

    --
    sumpsi - posui - clusi
    1. Tach!

      Bei Konstrukten wie solchen reagiere ich automatisch allergisch:

      $this->colTitles[$i] = mysqli_fetch_field_direct($this->$result, $i)->name ;
      switch (mysqli_fetch_field_direct($this->$result, $i)->type){
      

      Sowas sollte man cachen:

      $feldInfo = mysqli_fetch_field_direct($this->$result, $i);
      $this->colTitles[$i] = $feldInfo->name;
      switch ($feldInfo->type){
      

      Vor allem ist es unnötige Verdopplung. Wenn eine Information mehrfach verwendet wird, sollte man das auch im Code verdeutlichen, indem man sie nicht mehrfach abfragt, sondern nur einmal und das Ergebnis dann mehrfach verwendet. Ansonsten muss man genau hinschauen, um zu erkennen, ob der Codeteil der Abfrage identisch oder doch anders ist. Lieber eine Zeile mehr für die Eindeutigkeit.

      Es ist aber auch nicht optimal. Man weiß nicht, inwieweit der mysqli-Treiber diese Informationen puffert,

      Man kann da was wissen, aber es ist nicht (nur) der mysqli-Treiber sondern mysqlnd. mysqlnd ist eine Extension von PHP, die im Hintergrund arbeitet und für das alte mysql, mysqli und auch PDO eine andere Schnittstelle bietet als die herkömmliche MySQL-Client-API. Namentlich geht mysqlnd so weit, dass es das Memorymanagement von PHP verwendet. Das äußert sich dahingehend, dass die vom DBMS geholten Daten bereits intern in PHP-Form vorliegen. Alle Zugriffe müssen dann nicht erst noch ins PHP-Variablenformat umkopiert werden, sondern können gleich von den API-Funktionen im PHP-Stil zurückgegeben werden. Der PHP-Stil hört auf den Namen Copy-On-Write. Wenn ein Wert anscheinend kopiert wird, zum Beispiel beim Zuweisen einer Variable zu einer anderen, passiert das intern nicht, sondern es wird nur eine Art Referenz erzeugt. Erst wenn die Variableninhalte abweichen wird die Kopie tatsächlich erzeugt.

      Mit anderen Worten, das Cachen passiert intern wahrscheinlich schon. (Ich kann nicht für die Arbeitsweisen aller Funktionen sprechen, deswegen das "wahrscheinlich".) Zudem dürfte es im Bereich der Microoptimierung liegen. Performance ist also eher weniger das Thema, aber die Lesbarkeit von Code für Menschen ist wichtiger.

      dedlfix.