Martin Zuba: Variablen Zusammenstückeln

Hallo!

Ich bin gerade dabei mir PHP zu erlernen und meine Diplomacy-Seite PHP-basiert neu zu gestalten.
Momentan arbeite ich an einer Tabelle, in der von jeder Großmacht die Züge eingetragen werden sollen. Konkret sieht das so aus:

  
<?php  
  
$request = mysql_query("SELECT * FROM history WHERE jahr = {$currentyear} AND phase = {$currentphase}");  
    $info = mysql_fetch_object($request);  
  
...  
?>  
  
...  
<tr>  
<td class="moves"><img src="data/flag-ger.gif" width=35></td>  
  
        <td bgcolor="#CCCCCC">Deutschland</td>  
        <td class="moves"><?php echo nl2br($info->moves_germany);?></td>  
        <td class="moves"><?php echo nl2br($info->retreats_germany);?></td>  
        <td class="moves"><?php echo nl2br($info->adjustments_germany);?></td>  
  
      </tr>  
      <tr>  
        <td  class="moves"><img src="data/flag-fra.gif" width=35></td>  
        <td bgcolor="#CCCCCC">Frankreich</td>  
        <td class="moves"><?php echo nl2br($info->moves_france);?></td>  
        <td class="moves"><?php echo nl2br($info->retreats_france);?></td>  
        <td class="moves"><?php echo nl2br($info->adjustments_france);?></td>  
  
      </tr>  
      <tr>  
        <td class="moves"><img src="data/flag-uk.gif" width=35></td>  
        <td bgcolor="#CCCCCC">Gro&szlig;britannien</td>  
        <td class="moves"><?php echo nl2br($info->moves_england);?></td>  
        <td class="moves"><?php echo nl2br($info->retreats_england);?></td>  
        <td class="moves"><?php echo nl2br($info->adjustments_england);?></td>      </tr>  
      <tr>  
        <td class="moves"><img src="data/flag-ita.gif" width=35></td>  
        <td bgcolor="#CCCCCC">Italien</td>  
         <td class="moves"><?php echo nl2br($info->moves_italy);?></td>  
        <td class="moves"><?php echo nl2br($info->retreats_italy);?></td>  
        <td class="moves"><?php echo nl2br($info->adjustments_italy);?></td>      </tr>  
      <tr>  
        <td class="moves"><img src="data/flag-tur.gif" width=35></td>  
        <td bgcolor="#CCCCCC">Osmanisches Reich</td>  
         <td class="moves"><?php echo nl2br($info->moves_germany);?></td>  
        <td class="moves"><?php echo nl2br($info->retreats_germany);?></td>  
        <td class="moves"><?php echo nl2br($info->adjustments_germany);?></td>      </tr>  
      <tr>  
        <td class="moves"><img src="data/flag-aus.gif" width=35></td>  
        <td bgcolor="#CCCCCC">&Ouml;sterreich-Ungarn</td>  
         <td class="moves"><?php echo nl2br($info->moves_germany);?></td>  
        <td class="moves"><?php echo nl2br($info->retreats_germany);?></td>  
        <td class="moves"><?php echo nl2br($info->adjustments_germany);?></td>      </tr>  
       <tr>  
        <td class="moves"><img src="data/flag-rus.gif" width=35></td>  
        <td bgcolor="#CCCCCC">Russland</td>  
         <td class="moves"><?php echo nl2br($info->moves_germany);?></td>  
        <td class="moves"><?php echo nl2br($info->retreats_germany);?></td>  
        <td class="moves"><?php echo nl2br($info->adjustments_germany);?></td>      </tr>

Und das funktioniert auch. Nun dachte ich mir, ich könnte das ganze ein wenig übersichtlicher gestalten. Immerhin sind ja die Ländernamen in einer anderen Datenbank gespeichert, und wenn ich auch das automatisieren könnte, wäre die Homepage auch für Varianten mit anderen Ländern geeigent.

Ich bin also auf folgendes gekommen:

  
<?php  
  
$request = mysql_query("SELECT * FROM history WHERE jahr = {$currentyear} AND phase = {$currentphase}");  
    $info = mysql_fetch_object($request);  
  
...  
?>  
  
...  
  
<?php  
       $request2 = mysql_query("SELECT * FROM main");  
       while ($land = mysql_fetch_object($request2)) {  
     echo "<tr>";  
     echo "<td class=\"moves\"><img src=\"data/", $land->flag, "\" width=35></td>\n";  
     echo "<td bgcolor=\"#CCCCCC\">",$land->name_dt,"</td>\n";  
     echo "<td class=\"moves\">", nl2br($info->moves_{$land->name_en}),"</td>\n";  
     echo "<td class=\"moves\">", nl2br($info->retreats_{$land->name_en}),"</td>\n";  
     echo "<td class=\"moves\">", nl2br($info->adjustments_{$land->name_en}),"</td>\n";  
     echo "</tr>";  
    }  
    ?>  

Das funktioniert aber nicht, weil ich die Ländernamen aus Datenbank main anscheinend nicht in den Variablenname der Abfrage aus der Datenbank  history einfügen kann.

Gibt es hier eine elegante Lösung?

lg
Martin

  1. Hi,

    vielleicht reduzierst Du Deinen Quellcode mal aufs Wesentliche, wer soll da noch durchblicken...

    $request = mysql_query("SELECT * FROM history WHERE jahr = {$currentyear} AND phase = {$currentphase}");

    Da fehlen (maskierte) Anführungszeichen oder Hochkommas um die gesuchten Begriffe:
    $request = mysql_query("SELECT * FROM history WHERE jahr = "{$currentyear}"...

    Gruesse, Joachim

    --
    Am Ende wird alles gut.
  2. echo $begrüßung;

    Das funktioniert aber nicht, weil ich die Ländernamen aus Datenbank main anscheinend nicht in den Variablenname der Abfrage aus der Datenbank  history einfügen kann.

    "Funktioniert nicht" heißt in deinem Fall konkret was?

    Statt $info->moves_{$land->name_en} notiert man das korrekterweise $info->{'moves_' . $land->name_en}.

    $request = mysql_query("SELECT * FROM history WHERE jahr = {$currentyear} AND phase = {$currentphase}");

    Du hast sichergestellt, dass $currentyear und $currentphase unter allen Umständen Zahlenwerte enthalten, beispielsweise mit einer Zwangskonvertierung mittels intval()?

    Deinem Code fehlt außerdem das Auswerten von Fehlerzuständen, die durch den Rückgabewert der mysql_*-Funktionen bekanntgegeben werden.

    Gibt es hier eine elegante Lösung?

    Dein Tabellendesign ist ungünstig, du hast beim Abfragen ein Problem und du denkst nun, mit einer weiteren ungünstigen Geschichte namens variable Variablen dieses Problem lösen zu können. Elegant wäre es, das Tabellendesign zu ändern, so dass die Landesinformation beim Abfragen nicht in den Metadaten (Feldname) steckt sondern in den Daten, denn darauf kann man einfacher zugreifen als mit der Feldnamenzusammensetzmethode. Und wenn noch ein Land hinzukommt kann das einfach in den Daten ergänzt werden, ohne dass weitere Felder und Auswertungen hinzugenommen werden müssen.

    echo "$verabschiedung $name";

  3. Mahlzeit Martin Zuba,

    $request = mysql_query("SELECT * FROM history WHERE jahr = {$currentyear} AND phase = {$currentphase}");
    [...]
            <td class="moves"><?php echo nl2br($info->moves_germany);?></td>
            <td class="moves"><?php echo nl2br($info->retreats_germany);?></td>
            <td class="moves"><?php echo nl2br($info->adjustments_germany);?></td>

    Ich schätze, Du hast kein PHP-Problem, sindern ein Datenbankproblem. Wie sieht Dein Tabellendesign aus? Welche Spalten welchen Typs haben Deine Tabellen? Hast Du Dich über Normalisierung informiert und die Erkenntnisse entsprechend umgesetzt?

    Und das funktioniert auch. Nun dachte ich mir, ich könnte das ganze ein wenig übersichtlicher gestalten. Immerhin sind ja die Ländernamen in einer anderen Datenbank gespeichert, und wenn ich auch das automatisieren könnte, wäre die Homepage auch für Varianten mit anderen Ländern geeigent.

    Das mag sein - aber nicht mit dem Tabellendesign, das Du (wahrscheinlich) hast. So ist Deine Anwendung immer auf die Länder beschränkt, für die Du Spalten in Deiner Tabelle "history" vorgesehen hast. Für jedes neue Land musst Du Dein Tabellendesign ändern ... und das ist gemeinhin das deutlichste Anzeichen dafür, dass das Design Mist ist. :-)

    Ich bin also auf folgendes gekommen:

    Vergiss das bitte ganz schnell wieder.

    Gibt es hier eine elegante Lösung?

    Ja. Vernünftiges Tabellendesign (s.o.).

    MfG,
    EKKi

    --
    sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
    1. Mahlzeit Martin Zuba,

      $request = mysql_query("SELECT * FROM history WHERE jahr = {$currentyear} AND phase = {$currentphase}");
      [...]
              <td class="moves"><?php echo nl2br($info->moves_germany);?></td>
              <td class="moves"><?php echo nl2br($info->retreats_germany);?></td>
              <td class="moves"><?php echo nl2br($info->adjustments_germany);?></td>

      Ich schätze, Du hast kein PHP-Problem, sindern ein Datenbankproblem. Wie sieht Dein Tabellendesign aus? Welche Spalten welchen Typs haben Deine Tabellen? Hast Du Dich über Normalisierung informiert und die Erkenntnisse entsprechend umgesetzt?

      Das mag sein - aber nicht mit dem Tabellendesign, das Du (wahrscheinlich) hast. So ist Deine Anwendung immer auf die Länder beschränkt, für die Du Spalten in Deiner Tabelle "history" vorgesehen hast. Für jedes neue Land musst Du Dein Tabellendesign ändern ... und das ist gemeinhin das deutlichste Anzeichen dafür, dass das Design Mist ist. :-)

      Ich habe den Fehler inzwischen behoben, indem ich die "variablen Veriablen" richtig benannt habe. Du hast aber auf jeden Fall recht, dass das Design schlecht ist, vor allem weil ich für jedes neue Land die Struktur ändern muss. Der Wikipedia Link ist interessant, aber ich bin mir nicht sicher, wie ich meine Datenbank entsprechend verbessern kann. Ich könnte natürlich in eine Tabelle für jedes Land einen Eintrag machen, dann könnte ich so leicht neue Länder hinzufügen, dann müsste ich aber die Tabellenstruktur ändern, wenn ich ein neues Jahr+Phase einfüge.

      Brauche ich hierfür dreidimenionale Datenbanken? Oder wie soll ich das Problem sonst lösen? Ich beschäftige mich erst ein paar Tage mit PHP und mysql deshalb wäre ich für Tipps dankbar.

      Lg
      Martin