Kdo má dnes svátek?

12. září 2001

Proč nepřidat na každou stránku serveru malým písmem, kdo má svátek dnes a kdo zítra? A pokud se by to zrovna na ty vaše stránky nehodilo, dovíte se alepoň něco nového o PHP a databázích.

Na různých serverech, co jich na českém Internetu je, v jejich hlavičkách, patičkách či sloupcích se dovím, kolik máme zrovna hodin a kolikátého je dnes. Jistě, jsou to údaje důležité a proto si je můžu přečíst rovněž v liště pracovní plochy operačního systému. A to nejen MS Windows ale i MacOS a Linuxu.

Nedozvím se však, kdo má svátek, abych si na něj alespoň dnes vzpoměl. A to je ta věc, která se hodí místo data a času a která přispěje k oblíbenosti vašich stránek. Osobně jsem údaje o jmeninách vložil na svých stránkách účelně a nenápadně jen do SMS brány.

Jednoduché řešení

Vytvořím tedy PHP skript spolupracující s databází MySQL. Skript zjistí pořadové číslo dne v roce (počítáno od 1.1.), přičemž se musí vypořádat s přestupnými roky. Jména se v kalendáři každým rokem opakují ve stejném pořadí. A konečně podle pořadových čísel dnešního a zítřejšího dne vytáhne údaje z databáze. Skript začlením do zdrojového kodu stránky pomocí příkazu include (resp. require). Výstup vložím do generované stránky.

Databázová tabulka

V relační databázi (zde MySQL) mám uloženu tabulku jmen nazvanou svátek:

CREATE TABLE svátek (
  den int(3) NOT NULL,
  jmeno varchar(40) NOT NULL,
  PRIMARY KEY (den)
);

Tabulka má dva sloupce: pořadové číslo dne a jméno. Pořadové číslo je primárním klíčem (tj. jedinečnou neprázdnou hodnotou, podle které se tabulka indexuje}. Jistě jsem mohl zvolit za klíč jméno, ale číslo dne je kratší. Naopak, určitě by bylo lépe zvolit za klíč jméno, než nedávat klíč vůbec. Pomocí PhpMyAdminu jsem vygeneroval celý obsah tabulky svátek. V tabulce je 366 jmen, jedno z nich tedy patří 29. únoru.

Výpočet pořadových čísel dní

Funkce getdate() vrací asociatívní pole s datovými údaji. V indexu "yday" je pořadové číslo dne v roce počítáno od nuly. Pod indexem "mon" se skrývá číslo měsíce. Rok je v "year".

$datum=getdate(); // $datum je asociatívní pole
$dnes=++$datum["yday"]; // $dnes je pořadové číslo počítáno od jedné – zajistí preinkrementace ++
$mesic=$datum["mon"];
$rok=$datum["year"];

Výraz $dnes=++$datum["yday"] přiřazuje do proměnné $dnes hodnotu $datum["yday"] předtím zvýšenou o 1. Jedná se o tzv. preinkrementaci. Kdybych napsal $dnes=$datum["yday"]++ byla by hodnota $datum["yday"] nejprve přiřazena do $dnes a teprve potom zvýšena o 1, tzv. postinkrementaci tady nepotřebuji. Podobně to platí i pro dekrementaci pomocí –. Pro zjištění, zda je letos přestupný rok a zda je dnes již po 28. únoru se mi bude hodit číslo měsíce $datum["mon"] v proměnné $mesic a rok $datum["year"] v proměnné $rok. Pokračuji dále: Když není přestupný rok a je už alespoň březen, zvýším pořadové číslo dne o 1. Takto jsem přeskočil 29. únor, pro který mám v databázi také jméno.

if (($rok%4) && ($mesic>2)) $dnes++;

Přestupný rok je dělitelný 4. Zbytek po dělení $rok%4 by byl tedy 0, tj. false. V případě, že letošní rok má jen 365 dní, výraz $rok%4 vrací hodnotu nenulovou, tj. true. Dále může nastat situace, že dnes je 31.12. Zítra však není 32.12., jak by tvrdilo $zitra=$dnes+1, ale:

$zitra=$dnes%366+1;

Poslední chyták, který musím ošetřit: Když dnes je 28. února, zítra by mělo být 29. února, avšak letos není přestupný rok:

if (($rok%4) && ($zitra==60)) $zitra++;

Zjištění jmen z databáze

Konečně mám v proměnných $dnes a $zitra pořadová čísla dní a provedu dotaz v databázi:

mysql_connect($sql_server,$sql_uzivatel,$sql_heslo); // připojení k databázovému serveru
mysql_select_db($sql_databaze); // výběr databáze, ve které je tabulka svátek
list($svátek["dnes"])=mysql_fetch_row(mysql_query("select jmeno from svátek where den=$dnes")); // dnešní jméno
list($svátek["zitra"])=mysql_fetch_row(mysql_query("select jmeno from svátek where den=$zitra")); // zítřejší jméno

Při volání funkce mysql_connect() vícekrát během jednoho skriptu se stejnými hodnotami parametrů není vytvořeno pokaždé nové spojení; zůstává pořád jedno od prvního volání mysql_connect(). Tato skutečnost řeší problém, že některé skripty jsou už připojeny k databázi předtím, než dojde na svátek, jiné zase nikoli. Z podobných důvodů se od databáze na konci „svátek.php“ neodpojují. Jestliže by skript při svém dalším běhu potřeboval něco s databází, musela by se podruhé volat časově náročná funkce mysql_connect(). Naopak, když už skript databázi dále nepotřebuje, nevadi, spojení se automaticky uzavře po ukončení jeho běhu a funkce mysql_close() nezdržuje generování html stránky.

Poslední dva řádky se mohou zdát trochu málo výřečné. Liší se od sebe jen v "dnes" a "zitra" resp. $dnes a $zitra. Nejprve skript provede nad databází dotaz mysql_query(), výsledek dotazu je tabulka o jednom sloupci a jednom řádku. Jedno volání mysql_fetch_row() načte všechny (tedy jeden) sloupce jednoho (a jediného) řádku do pole. Nalevo list() přečte všechny (tedy jeden) prvky pole v pořadí dle jejich setřídění a vloží je do proměnných v závorkách. Proměnné v list() jsou argumenty voláné odkazem.

Vložení jmen do generované stránky

Výstupy skriptu jsou uloženy v asociatívním poli $svátek v indexech "dnes" a "zitra". Pomocí např. tabulek a kaskádových stylů je zakomponuji do stránky.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *