ESKA: Jahresüberblick mit PHP/MySQL wie besser machen?

Hallo,
habe mir einen kleinen Jahresübersichtskalender erstellt in dem fix Reisetermine und auch optionale und angefragte Reisetermine auftauchen (für den schnellen Überblick wann bin ich oder mein Kollege wo).
Läuft eigentlich auch ohne Probleme, außer daß er Ewigkeiten zum laden braucht (nachdem wir jetzt doch schon sehr viele Termine für viele Leute eingegeben haben - abfrage läuft übrigens pro Kollege Also Kalender für Hans, Kalender für Bernd,etc.)
Da dieses Teil eins meiner ersten Projekte in PHP/MySql ist, ist es auch noch sehr kompliziert aufgebaut.

Daher die Frage wie kann man es besser machen?

Kann man die Abfrage beschleunigen (durch joins oder ähnliches)

Kann man die Ausgabe besser machen (oder viel mehr wie kann man...)
Ich frage zuerst ab ob der Termin tatsächlich existiert (30.02. gibt es nun mal nicht...)
Dann ob der Tag auf ein Wochenende fällt
dann ob an dem Tag ein Termin existiert
und wenn ja wie der Status des Termines ist.
Je nach Ergebniss wird die Tabellenzelle bzw. die Schrift mit anderen Farben formatiert.
Hier mal den Code (ich hoffe, ich habe nichts rausgelöscht, da ich diverse internen ANgaben natürlich verbergen muß....):
----
<?
echo "<table border='1'>";
echo "<tr>";
echo "<td width='20'></td>";
echo "<td width='65'>Januar</td>";
echo "<td width='65'>Februar</td>";
echo "<td width='65'>März</td>";
echo "<td width='65'>April</td>";
echo "<td width='65'>Mai</td>";
echo "<td width='65'>Juni</td>";
echo "<td width='65'>Juli</td>";
echo "<td width='65'>August</td>";
echo "<td width='65'>September</td>";
echo "<td width='65'>Oktober</td>";
echo "<td width='65'>November</td>";
echo "<td width='65'>Dezember</td>";
echo "<td width='20'></td>";
echo "</tr>";

$i=1;
//-- i=Monat
$j=1;
//-- j=Tag
$k=$Date_Year;
while ($j<32)
{
echo "<tr>";
echo "<td width='20'>$j</td>";
while ($i<=12)
{
$sql = "select ID, Status, City, No from Table where C_ID=$C_ID && Date_Year=$Date_Year && Date_Month=$i && Date_Day=$j ORDER BY Select_Date";
/*Select_Date ist Datum im Datumsformat; Date_Year, Date_Month, und Date_Day sind extra Felder mit den jeweiligen Angaben; Das Jahr und die Kollegen ID wird von einem Formular übergeben*/

$erg = mysql_query($sql);
if (!$erg) die("<br>Abfrage nicht erfolgreich");
else
{
$m=mktime(12,0,0,$i,$j,$k);
$tag=getdate($m);
$menge = mysql_num_rows($erg);
$check1 = checkdate($i,$j,$k);
if($check1 != 1)
{
echo     "<td width='65' bgcolor='#000000'></td>";
}
else
{
if($tag[weekday]==Saturday || $tag[weekday]==Sunday)
{

if ($menge==1)
{
$Aus = mysql_fetch_array($erg);
if($Aus["Status"]==O || $Aus["Status"]==R)
{
echo     "<td class='rg'><a href='xxx.php?ID=" .$Aus["ID"]."'>" .$Aus["City"] ."</a></td>";
}
elseif ($Aus["Status"]==P)
{
echo     "<td class='bg'><a href='xxx.php?ID=" .$Aus["ID"]."'>" .$Aus["City"] ."</a></td>";
}
else
{
echo     "<td class='gg'><a href='xxx.php?ID=" .$Aus["ID"]."'>" .$Aus["City"] ."</a></td>";
}
}
elseif ($menge>1)
{
$Aus = mysql_fetch_array($erg);
echo     "<td class='rg'><a href='xxx.php?No=" .$Aus["No"] ."'> $menge Termine</a></td>";
}
else
{
echo     "<td class='gg'>..</td>";
}
}
else
{
if ($menge==1)
{
$Aus = mysql_fetch_array($erg);
if($Aus["Status"]==O || $Aus["Status"]==R)
{
echo     "<td class='wg'><a href='xxx.php?ID=" .$Aus["ID"]."'>" .$Aus["City"] ."</a></td>";
}
elseif ($Aus["Status"]==P)
{
echo     "<td class'wb'><a href='xxx.php?ID=" .$Aus["ID"]."'>" .$Aus["City"] ."</a></td>";
}
else
{
echo     "<td class='wb'><a href='xxx.php?ID=" .$Aus["ID"]."'>" .$Aus["City"] ."</a></td>";
}
}
elseif ($menge>1)
{
$Aus = mysql_fetch_array($erg);
echo     "<td class ='wr'><a href='xxx.php?No=" .$Aus["No"] ."'> $menge Termine</a></td>";
}
else
{
echo     "<td class 'wb'>..</td>";
}
}
}
}
$i++;
}
echo "<td class='wb'>$j</td>";
echo "</tr>";
$i=1;
$j++;
}
$j=1;

echo "</table>";
?>
----

Also falls euch was auffällt und Ihr Anregungen habt wie man das besser machen kann, wäre ich sehr dankbar.

Beste Grüße,
ESKA

  1. Daher die Frage wie kann man es besser machen?

    Wenn ich's Dir mal ganz unverblümt vor den Latz knallen darf: Dein Schreibstil ist saumäßig. Ganz besonders "schön" sind Stellen wie folgende:

    }
      }
      }
      }
      $i++;
      }

    Da weiß man doch gleich mit einem einzigen Blick, welche Klammer zu welchem if gehört..

    Bitte gewöhne Dir an, Deine Programme zu strukturieren. Einfach alles stur untereinander in der ersten Spalte zu beginnen, fördert nicht gerade die Übersichtlichtkeit. Das mag Dir wurscht sein, aber wenn Du andere mit dem Code beglücken möchtest, tust Du gut daran, Ihnen den Einstieg zu erleichtern.

    Dazu gehört auch, daß Variablennamen nicht erklärt werden müssen, sondern sich selbst erklären:

    $i=1;
      //-- i=Monat
      $j=1;
      //-- j=Tag
      $k=$Date_Year;

    Warum nennst Du die drei nicht einfach $tag, $monat, $jahr? Natürlich hast Du lange genug damit gearbeitet, um zu wissen, was i, j und k bedeuten mögen, aber jemand, der (wie hier im Forum) in Deinen Code stolpert, muß bei jeder Verwendung erstmal oben bei Deiner Erklärung nachschauen. Und Du in drei Monaten garantiert auch.

    Zur eigentlichen Frage:

    • Die Datenbanktabelle enthält eine Menge Daten doppelt, genauer gesagt jene für den Zeitpunkt (viermal). Schmeiße Date_Year, Date_Month und Date_Day raus. Willst Du einen Tag haben, vergleiche mittels

    $tag=sprintf(%04d%02d%02",$jahr,$monat,$tag);
      $sql="[..] zeit>=".$tag."000000 and zeit<=".$tag."235959";

    Vergiss nicht, einen Index über die Zeitspalte anzulegen.

    • Du prüfst das Datum erst, nachdem Du die DB-Abfrage gemacht hast. Benutze checkdate() als erstes.

    • Liegt mehr als ein Termin pro Tag vor, gibst Du außer einer Detailadresse gar nichts aus. Füge an den SQL-Befehl entweder "limit  2", damit er sich nach dem zweiten Termin keine Mühe mehr machen muß.

    • Die SQL-Sortierung ist bei Dir im Moment nutzlos: Du fragst nur einen Termin pro Tag ab.

    • Ich habe es zwar nie ausprobiert, aber ich bin der Meinung, daß Anfragen an ein externes System (sprich: MySQL) eine Menge Zeit verbraten. Diese Anfragen sollten dementsprechend möglichst viel auf einmal "ranschaffen":

    select ID,Status,City,No,dayofmonth(zeit) as tag,month(zeit) as monat,weekday(zeit) as wtag,count(*) as anzahl from Table where C_ID=$C_ID and year(select_date)=$jahr group by dayofyear(select_date)

    Dann:

    while ($termin=mysql_fetch_assoc(..))
        $termine[$termin["monat"]][$termin[$tag]]=$termin;

    Dann:

    for ($monat=1;$monat<=12;$monat++)
       {
        for ($tag=1;$tag<=31;$tag++)
         {
          if (checkdate($monat,$tag,$jahr))
            {
             if (isset($termine[$monat][$tag]))
               {
                if ($termine[$monat][$tag]["anzahl"]>1)
                   echo "mehrere termine";
                 else
                   echo "ein termin, wochentag=".$termine[$monat][$tag]["wtag"];
               }
              else
               {
                echo "kein termin";
               };
            }
           else
            {
             echo "ungültiger tag";
            };
         };
       };

    So in dem Dreh.

    Gruß,
      soenk.e

    1. Hallo,

      Wenn ich's Dir mal ganz unverblümt vor den Latz knallen darf: Dein Schreibstil ist saumäßig.

      Darfts Du gerne, denn da kann ich nun wirklich nichts gegen sagen - stimmt in dem Fall einfach

      Ganz besonders "schön" sind Stellen wie folgende:

      Da weiß man doch gleich mit einem einzigen Blick, welche Klammer zu welchem if gehört..

      Ja, mehr als Zehn Klammer dürfen nicht verwendet werden, denn dann sind die Finger zuende.....

      Dazu gehört auch, daß Variablennamen nicht erklärt werden müssen, sondern sich selbst erklären:

      $i=1;
        //-- i=Monat
        $j=1;
        //-- j=Tag
        $k=$Date_Year;

      Warum nennst Du die drei nicht einfach $tag, $monat, $jahr?

      Auch hier muß ich sagen stimmt, aber wie gesagt, das war mein erster Versuch in PHP und bei den Beispielen bekommt man halt immer $i etc. und da dachte ich mir, ich halt mich mal dran - wobei der Variablenname natürlich egal ist und es besser ist, daß man auf anhieb sieht was Sache ist.

      Zur eigentlichen Frage:

      Zu den eigentlichen Lösungsvorschlägen:

      Super! Vielen Dank für die Hinweise! Das da doppelt gemoppelt ist , war mir klar aber in meiner anfänglichen Naivität dachte ich mir sicher ist sicher und war mir mit den einzelnen Möglichkeiten (besonders was das Datumsfeld angeht) auch nicht so sicher - ehrlich gesagt war ich schlicht und ergreifend stolz, daß es funktioniert hat und nun möchte ich es natürlich auch noch sinnvoll gestalten.
      Also werde ich mir am Wochenende versuchen Deine Vorschläge umzusetzen.

      Also nochmals vielen Dank für die Hilfe und schönes Wochenende,
      ESKA