Verfasst am: 17.11.2008
Autor: Stephan Altmann
Beispielsweise viele Blogscripte bieten die Möglichkeit, nur Einträge eines bestimmten Monats nach Klick auf dem entsprechenden Link auszugeben. Eine solche Funktion lässt sich relativ einfach ohne größeren Aufwand realisieren.
Wichtig für die Umsetzung ist zuallererst, dass man sich dafür entscheidet, wie man die Datensätze mit einer genauen Zeitangabe versieht. Ich persönlich ziehe den UNIX-Timestamp dem MySQL-Timestamp vor, da ich zumeist mittels PHP auf die Daten zugreife und sich Datumsangaben in diesem Format mit Hilfe von PHP relativ einfach handhaben lassen. Ebenso bestünde die Möglichkeit, die einzelnen Bestandteile des Datums auf mehrere Spalten aufzuteilen, was bei einer derartigen Funktion, wie wir sie hier realisieren wollen, durchaus einen Vorteil mit sich brächte. Allerdings bin ich persönlich der Ansicht, dass, wenn ich ohne bedeutenden Mehraufwand mit weniger Spalten auskomme, ich auch mit weniger Spalten arbeiten sollte, da sich so UPDATE- und INSERT-Anfragen kürzer und somit übersichtlicher halten lassen
Erläuterung zum Unterschied von UNIX- & MySQL-Timestamp:
Ein UNIX-Timestamp entspricht der Anzahl der Sekunden seit dem 1. Januar 1970 0.00 Uhr. Ein MySQL-Timestamp hingegen wird in der Form „YYYY-MM-DD HH:MM:SS“ dargestellt.
In PHP erzeuge ich einen den UNIX-Timestamp der aktuellen Uhrzeit ganz einfach durch das Aufrufen der Funktion time() ohne Angabe irgendwelcher Parameter.
PHP-Code:
//Ausgabe der aktuellen Uhrzeit als UNIX-Timestamp
echo time();
//Ausgabe der aktuellen Uhrzeit als MySQL-Timestamp
SELECT NOW();
SELECT NOW();
//Umwandlung eines UNIX-Timestamps
SELECT FROM_UNIXTIME(`spalte`) FROM `tabelle`
//Umwandlung und formatierte Ausgabe des Jahres
SELECT FROM_UNIXTIME(`spalte`, '%Y-%m') FROM `tabelle`
//Ergebnis (November 2008): 2008-11
SELECT FROM_UNIXTIME(`spalte`) FROM `tabelle`
//Umwandlung und formatierte Ausgabe des Jahres
SELECT FROM_UNIXTIME(`spalte`, '%Y-%m') FROM `tabelle`
//Ergebnis (November 2008): 2008-11
Die Funktionsweise werde ich an dieser Stelle nur anhand eines gekürzten Beispiels darstellen. Mit den hier vorgestellten Funktionen werden wir im Verlaufe des Tutorials arbeiten, weshalb ich hier grob darauf eingehen werde. Für ausgiebige Informationen bezüglich jeweiligen Funktion empfehle ich es, einen Blick ins PHP-Handbuch (http://www.php.net/manual/de/) zu werfen.
PHP-Code:
//Auszug MySQL-Timestamp (2008-11)
//Auslesen von Jahr und Monat
$jahr = substr(“2008-11”, 0, 4);
$monat = substr(“2008-11”, 5, 2);
//Umwandlung in UNIX-Timestamp
$timestamp = mktime($stunde, $minute, $sekunde, $monat, $tag, $jahr);
//Rückumwandlung in Ausgangsstring (2008-11)
echo $date(“Y-m”, $timestamp);
Wenn wir mit vorzeichenbehafteten 32-Bit-Integerwerten (Wertebereich −2.147.483.648 bis +2.147.483.647) arbeiten, ergibt sich daraus das Problem, dass sich ein Timestamp von vor dem 13. Dezember 1902 und nach dem 19. Januar 1938 nicht darstellen lässt. In einem solchen Fall erhalten wir einen Integerüberlauf. Ebenso werden derzeit keine negativen Werte für Timestamps unter Windows unterstützt. Für die Speicherung von beispielsweise Geburtsdaten empfiehlt sich der Timestamp daher nicht.
Schritt 1: Anlegen der Datenbank
Zuallererst legen wir folgende Tabelle an.
CREATE TABLE IF NOT EXISTS `blog_entries` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(255) NOT NULL,
`content` text NOT NULL,
`date` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
`id` int(11) NOT NULL auto_increment,
`title` varchar(255) NOT NULL,
`content` text NOT NULL,
`date` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
Ich kann und will in diesem Tutorial nicht auf sämtliche Grundlagen eingehen. Ich gehe davon aus, dass allgemein bekannt ist, wie man eine MySQL-Verbindung aus einem PHP-Script heraus aufbaut und wie man Daten in einer Tabelle speichert. Für letzteres will ich kurz ein Beispiel geben:
PHP-Code:
$date = time();
mysql_query("INSERT INTO `blog_entries` (`title`, `content`, `date`) VALUES ('" . addslashes($_REQUEST["title"]) . "', '" . addslashes($_REQUEST["content"]) . "', '$date')");
Beim Arbeiten mit Benutzereingaben empfiehlt es sich grundsätzlich, diese mittels addslashes() zu maskieren, um MySQL-Injections zu verhindern.
Schritt 2: Kategorienauswahl generieren
Zuerst definieren wir folgendes Array:
PHP-Code:
$monate = array("01" => "Januar",
"02" => "Feber",
"03" => "März",
"04" => "April",
"05" => "Mai",
"06" => "Juni",
"07" => "Juli",
"08" => "August",
"09" => "September",
"10" => "Oktober",
"11" => "November",
"12" => "Dezember");
PHP-Code:
$back_year = 0;
$query = mysql_query("SELECT FROM_UNIXTIME(`date`, '%Y%m') AS ym, COUNT(`id`) AS count FROM `blog_entries` GROUP BY ym DESC");
while($_MONTHS = mysql_fetch_assoc($query))
{
$_YEAR = substr($_MONTHS["ym"], 0, 4);
$_MONTH = substr($_MONTHS["ym"], 4, 2);
if($_YEAR != $back_year) echo "<br /><b>" . $_YEAR . "</b><br />";
echo "<a href=\"index.php?date=$_MONTHS[ym]\">" . $monate[$_MONTH] . "</a> (" . $_MONTHS["count"] . ")<br />";
$back_year = $_YEAR;
}
Wir initialisieren zuerst eine Variable namens „$back_year“ indem wir ihr den Wert 0 zuweisen. Eigentlich ist dies in PHP nicht unbedingt erforderlich, da Variablen anders als beispielsweise in C nicht ohne explizite Wertzuweisung auf jeden möglichen Speicherbereich verweisen können. Dennoch rate ich gerade bei wirklich komplexen Skripten dazu, dies zu tun, da es durchaus vorkommen, dass eine Variable gleichen Namens bereits verwendet wurde.
PHP-Code:
$query = mysql_query("SELECT FROM_UNIXTIME(`date`, '%Y%m') AS ym, COUNT(`id`) AS count FROM `blog_entries` GROUP BY ym DESC");
PHP-Code:
while($_MONTHS = mysql_fetch_assoc($query))
{
}
PHP-Code:
$_YEAR = substr($_MONTHS["ym"], 0, 4);
$_MONTH = substr($_MONTHS["ym"], 4, 2);
PHP-Code:
if($_YEAR != $back_year) echo "<br /><b>" . $_YEAR . "</b><br />";
echo "<a href=\"index.php?date=$_MONTHS[ym]\">" . $monate[$_MONTH] . "</a> (" . $_MONTHS["count"] . ")<br />";
$back_year = $_YEAR;
Den eigentlichen Monat geben wir als Link aus. Wie zuvor angekündigt bedienen wir uns an dieser Stelle des Arrays mit den deutschen Datumsnamen. Über den Link übergeben wir der nach einem Klick aufgerufenen Seite unsere Datumszeichenkette.
Schritt 3: Ausgabe der Datensätze
Abschließend geben wir die Datensätze wie folgt aus:
PHP-Code:
if($_REQUEST["date"])
{
$year = substr($_REQUEST["date"], 0, 4);
$month = substr($_REQUEST["date"], 4, 2);
//$min = erster Tag des Monat 00:00:00
$min = mktime(0, 0, 0, $month, 1, $year);
//$max = letzter Tag des Monats; 23:59:59
$max = mktime(0, 0, 0, $month + 1, 1, $year);
$query = $database->db_query("SELECT * FROM `blog_entries` WHERE `date` >= '" . addslashes($min) . "' and `date` < '" . addslashes($max) . "' ORDER BY `date`DESC");
}
else $query = $database->db_query("SELECT * FROM `blog_entries` ORDER BY `date`DESC");
while($_ARTICLE = mysql_fetch_assoc($query))
{
echo "<br /><b>" . $_ ARTICLE[“title”] . "</b><br />" . $_ ARTICLE[“content”];
}
PHP-Code:
if($_REQUEST["date"])
{
//…
}
else $query = $database->db_query("SELECT * FROM `blog_entries` ORDER BY `date`DESC");
while($_ARTICLE = mysql_fetch_assoc($query))
{
echo "<br /><b>" . $_ ARTICLE[“title”] . "</b><br />" . $_ ARTICLE[“content”];
}
PHP-Code:
if($_REQUEST["date"])
{
$year = substr($_REQUEST["date"], 0, 4);
$month = substr($_REQUEST["date"], 4, 2);
//$min = erster Tag des Monats 00:00:00
$min = mktime(0, 0, 0, $month, 1, $year);
//$max = erster Tag des nächsten Monats 00:00:00
$max = mktime(0, 0, 0, $month + 1, 1, $year);
$query = $database->db_query("SELECT * FROM `blog_entries` WHERE `date` >= '" . addslashes($min) . "' and `date` < '" . addslashes($max) . "' ORDER BY `date`DESC");
}
In der WHERE-Klausel der Abfrage fügen wir abschließend die obige Bedingung ein, um zu erwirken, dass lediglich Beiträge zwischen diesen 2 Zeitpunkten ausgelesen werden. Da es unter Umständen vorkommen kann, dass ein Beitrag Punkt 00:00:00 am darauffolgenden Monat erstellt werden kann, müssen wir, damit dieser nicht dem falschen Monat zugewiesen wird, vom Vergleichsoperator „<“ Gebrauch machen, während wir beim Minimalwert „>=“ verwenden.
Korrektur
Wenn ich schon darauf hinweise, dass ich Benutzereingaben manuell mittels addslashes() maskiere, sollte ich diese natürlich auch wieder demaskieren.
Daher sollte der Auslesevorgang sich wie folgt darstellen:
PHP-Code:
echo "<br /><b>" . stripslashes($_ ARTICLE[“title”]) . "</b><br />" . stripslashes($_ ARTICLE[“content”]);
Wie handhabe ich dies?
Ganz einfach mittels
PHP-Code:
if(get_magic_quotes_gpc())
Dies ist nicht Gegenstand des Tutorials, sollte aber, da dieses in erster Linie für Neulinge geschrieben wurde, doch angemerkt werden.
weitere Anmerkungen
Ich wurde darauf hingewiesen, dass ebenso von der Funktion mysql_real_escape_string() anstelle von addslashes() Gebrauch gemacht werden kann bzw. diese sogar dieser vorzuziehen ist. Grundsätzlich muss ich dem zustimmen, allerdings nicht aus sicherheitsrelevanten Gründen. (Stichworte: konsequente Maskierung, Zeichensatzaspekte, ...)
Ich persönlich nehme Abstand von dieser Funktion, da diese eine geöffnete Datenbankverbindung erfordert und diese einem beispielsweise, wenn man SQL-Anweisungen für externe Scripte aufbereitet, nicht zur Verfügung steht.




Bereiche
Kategorien
Forum - Programming





tutorials.de-Systemmitteilung