Thomas G.: mysql_query --> list()=each() : Was mach ich falsch

Hallo,

ich habe folgenden Code:

$typtxt = (mysql_query("select * from pk_types where id = '$at_typ'"));

/*ZEILE 61*/ while(list($id, $typ) = each(mysql_fetch_row($typtxt)))
{
   print("Typ der Attacke: $typ");
}

hierbei ist dazuzusagen, dass das Ergebnis nur 1 Zeile hat, vielleicht liegt es daran ...

als Fehlermeldung bekomme ich: Warning: Variable passed to each() is not an array or object in /home/thgraf01/htdocs/pk/pokedex/attacken/effect.php on line 61

ich hoffe es kann mir jemand helfeb
vielen dank im Voraus

Thomas G.

  1. Moin,

    als Fehlermeldung bekomme ich: Warning: Variable passed to each() is not an array or object in /home/thgraf01/htdocs/pk/pokedex/attacken/effect.php on line 61

    Lass dir doch den Rückgabewert von mysql_fetch_row() einfach mal mit print_r ausgeben. Das sollte nämlich FALSE zurückgeben, wenn es keine weiteren Zeilen mehr gibt. Und FALSE ist ja nun eindeutig kein Array ;)

    --
    Henryk Plötz
    Grüße aus Berlin

  2. Aloha!

    $typtxt = (mysql_query("select * from pk_types where id = '$at_typ'"));

    /*ZEILE 61*/ while(list($id, $typ) = each(mysql_fetch_row($typtxt)))
    {
       print("Typ der Attacke: $typ");
    }

    Warum denn so kompliziert? mysql_fetch_array() verwenden hilft:

    while ($attacke = mysql_fetch_array($typtxt))
    {
      print ("Typ der Attacke: ".$attacke['typ'];
    }

    Die Funktion mysql_fetch_array gibt dir einen Hash. Die Schlüssel entsprechen den Spalten deiner Datenbanktabelle (obiges Beispiel setzt also voraus, daß der Typ der Attacke in der Spalte 'typ' steht).

    Die Funktion gibt false zurück, wenn keine weitere Zeile mehr vorliegt, und bricht damit die while-Schleife ab.

    Außerdem entgehst du damit einer weiteren Falle, die du - vermutlich ohne es zu wissen - eingebaut hast: Solltest du deine Datenbanktabelle jemals um eine Spalte erweitern bzw. sollte sich die Reihenfolge der Spalten in der Datenbank durch irgendeinen dummen Zufall mal ändern, hättest du ein Problem mit _deinem_ Code. Du selektierst alle Spalten (SELECT * ist böse), auch die, von denen du heute noch nicht weißt, daß es sie vielleicht geben wird, und du gibst durch das Sternchen auch keine Reihenfolge vor. Du vertraust aber blind darauf, daß mysql_fetch_row dir genau _zwei_ Spaltenergebnisse in der von dir gewünschten Reihenfolge liefert.

    mysql_fetch_array hat diese Probleme alle nicht. Du hast zwar den Nachteil, daß du die Hash-Variable nicht direkt in Stringausgaben einbauen kannst, aber das ist wirklich Gewöhnungssache.

    - Sven Rautenberg

    1. Hallo Sven,

      while ($attacke = mysql_fetch_array($typtxt))
      Die Funktion mysql_fetch_array gibt dir einen Hash.

      wirklich?
      Nicht vielleicht eine Referenz auf einen Hash?
      Denn einen ganzen Hash in einem Skalar zu speichern,
      das könnte etwas kompliziert werden ...

      Du hast zwar den Nachteil, daß du die Hash-Variable
      nicht direkt in Stringausgaben einbauen kannst,

      Wieso nicht? Am Hash selbst kann es nicht liegen ...
      höchstens an der Adressierung über die Referenz.

      Viele Grüße
            Michael

      1. Aloha, Michael!

        while ($attacke = mysql_fetch_array($typtxt))
        Die Funktion mysql_fetch_array gibt dir einen Hash.

        wirklich?
        Nicht vielleicht eine Referenz auf einen Hash?
        Denn einen ganzen Hash in einem Skalar zu speichern,
        das könnte etwas kompliziert werden ...

        Wir sind hier im Gebiete von PHP - da heißen alle Variablen mit Vornamen "$", egal welchen "Beruf" sie haben. Das mag für Perl-Puristen befremdlich erscheinen, ist aber meiner Meinung nach durchaus vernünftig und eine Hemmschwelle weniger für die Allgemeinheit.

        Du hast zwar den Nachteil, daß du die Hash-Variable
        nicht direkt in Stringausgaben einbauen kannst,

        Wieso nicht? Am Hash selbst kann es nicht liegen ...
        höchstens an der Adressierung über die Referenz.

        Weil man nicht sowas machen kann:
        echo "Das ist der Inhalt von $attacke.";
        ergibt
        Das ist der Inhalt von array.

        Ein einzelnes Element ausgeben (was man bei Arrays/Hashes ja eher möchte):
        echo "Das ist der Inhalt von $attacke['schluessel'].";
        ergibt einen Fehler. Es muß so heißen:
        echo "Das ist der Inhalt von " . $attacke['schluessel'] . ".";

        Etwas nervig, aber Gewöhnungssache.

        - Sven Rautenberg

        1. Hallo Sven,

          Wir sind hier im Gebiete von PHP - da heißen alle
          Variablen mit Vornamen "$", egal welchen "Beruf"
          sie haben.

          ah - danke, das wußte ich nicht.

          Das heißt, bei PHP wären $x[1] und $x['1'] Zugriffe
          auf zwei verschiedene Variablen (einen Array und
          einen Hash - vorausgesetzt, die Syntax existiert
          überhaupt in dieser Form)?

          Das mag für Perl-Puristen befremdlich erscheinen,
          ist aber meiner Meinung nach durchaus vernünftig
          und eine Hemmschwelle weniger für die Allgemeinheit.

          Ich bin kein Perl-Purist - ich mag allerdings keine
          "überladenen Operatoren", die je nach Kontext unter-
          schiedliche Bedeutungen haben.
          Insofern finde ich die Aufteilung in Perl besser -
          allerdings auch dort inkonsequent, weil das Ansprechen
          eines Elements eines Hashes bzw. Arrays dort als Skalar
          notiert werden muß.

          Ein einzelnes Element ausgeben (was man bei Arrays/Hashes ja eher möchte):
          echo "Das ist der Inhalt von $attacke['schluessel'].";
          ergibt einen Fehler. Es muß so heißen:
          echo "Das ist der Inhalt von " . $attacke['schluessel'] . ".";
          Etwas nervig, aber Gewöhnungssache.

          Hm, ja.

          Viele Grüße
                Michael

          1. Aloha, Michael!

            Das heißt, bei PHP wären $x[1] und $x['1'] Zugriffe
            auf zwei verschiedene Variablen (einen Array und
            einen Hash - vorausgesetzt, die Syntax existiert
            überhaupt in dieser Form)?

            Je nachdem, was man denn so als Variable bezeichnen mag...

            $x ist eine Variable - ganz klar. :) Und da es in PHP nur Hashes gibt (und Arrays einfach eine spezielle Form eines Hashes ist), sprichst du mit $x[1] in der Arrayform einen Speicherplatz an, und mit $x['1'] in der Hashform. Beides läuft in diesem Fall auf dasselbe heraus - es ist dieselbe Variable bzw. derselbe Wert, der angesprochen wird.

            Ich bin kein Perl-Purist - ich mag allerdings keine
            "überladenen Operatoren", die je nach Kontext unter-
            schiedliche Bedeutungen haben.
            Insofern finde ich die Aufteilung in Perl besser -
            allerdings auch dort inkonsequent, weil das Ansprechen
            eines Elements eines Hashes bzw. Arrays dort als Skalar
            notiert werden muß.

            Naja, Perl ist in dieser Hinsicht schon konsequent: Wenn man einen Skalar haben will, muß man das mit $variable tun. Wobei variable eben auch Arrayteil oder Hashteil sein kann - Hauptsache, vorne steht das $.

            Man ist es von anderen Programmiersprachen aber gewöhnt, dass das Sonderzeichen vorn (sofern es denn überhaupt notwendig ist) den Variablentyp angibt - $ als Stringvariable, @ als Arrayvariable und % als Hashvariable. Warum kann man nicht auf $string, @array[23] und %hash['key'] zugreifen, wenn man das schon unbedingt trennen muß? Nein, man muß Perl immer wieder daran erinnern, welcher Typ des Variablenzugriffs nun gemeint ist, und streng darauf achten, daß man einen Hash mit %hash2 = %hash1 kopiert, aber mit echo $hash1['key'] einen enthaltenen String ausgibt. Ist in meinen Augen Programmiererschikane. ;->

            - Sven Rautenberg