PHP triky

Weblog o elegantním programování v PHP pro mírně pokročilé

Nechce mi někdo navrhnout design?

Jak můžete vidět na těchto stránkách, nemám zrovna vyvinuté grafické cítění. Většina lidí na tom určitě bude líp a tak jsem se chtěl zeptat, jestli by mi někdo nechtěl navrhnout design těchto stránek. Potřeboval bych logo, ikonu a CSS nebo jenom grafický návrh v podobě obrázku, rozřezání už si dokážu zajistit sám.

Předpokládám, že to každý bude považovat za svou čest :-), ale i tak nabízím určité protihodnoty: Jednak uvedení jména a odkazu na autora designu na těchto stránkách po celou dobu jeho nasazení a jednak naprogramování nějaké menší PHP aplikace nebo komponenty podle přání ať už hned nebo jako příslib do budoucna.

Kontaktovat mě můžete na e-mailu vrana@php.net.

Jakub Vrána, Ze zákulisí, 20.2.2006, diskuse: 19 (nové: 0) - vložit příspěvek

Rok pryč

No vida. Rok je pryč a snaha vydávat články každé pondělí, středu a pátek mi vydržela celou dobu, takže za tu dobu vyšlo celkem 157 příspěvků. Někomu jistě některá témata přišla moc jednoduchá, složitá nebo prostě nezajímavá. Věřím ale, že jsme se všichni vzájemně obohatili, rozšířili své obzory a alespoň trochu se zdokonalili. Děkuji za příspěvky do diskuse, které jsou ve většině případů konstruktivní, i dobře mířený dotaz může čtenáře navést správným směrem, podpásovek nebo sprosťáren je naštěstí minimum.

Kompletní seznam příspěvků naleznete v archivu, na tomto místě nabízím příspěvky seřazené do kalendáře:

<?php
$data = array();
$result = mysql_query("SELECT publikovano, url, nadpis FROM clanky WHERE publikovano <= NOW() ORDER BY publikovano");
while ($row = mysql_fetch_assoc($result)) {
    $data[$row["publikovano"]] = "<a href='$row[url].php' class='inner' title='" . htmlspecialchars($row["nadpis"], ENT_QUOTES) . "'>";
}
mysql_free_result($result);

for ($i=mktime(2, 0, 0, 2, 1, 2005); $i < mktime(4); $i += 24*60*60) {
    $w = date("w", $i);
    $j = date("j", $i);
    if ($j == 1) {
        echo ($i != mktime(2, 0, 0, 2, 1, 2005) ? "</tr>\n</table></div>\n" : "") . "<div style='margin-right: 1em; height: 14em; float: left;'><table cellspacing='0' cellpadding='3'>\n<tr><th colspan='7'>" . date("n/Y", $i) . "</th></tr>\n<tr>" . ($w != 1 ? "<td colspan='" . (($w + 6) % 7) . "'> </td>" : "");
    }
    echo "<td>" . (isset($data[date("Y-m-d", $i)]) ? $data[date("Y-m-d", $i)] . "$j</a>" : $j) . "</td>";
    echo ($w == 0 && $j != date("t", $i) ? "</tr>\n<tr>" : "");
}
echo "</tr>\n</table></div>\n";
?>

Co dál? Pár témat v šuplíku ještě mám, ale rozhodně uvítám i jakékoliv vaše náměty. Pravidelná frekvence vydávání asi časem skončí, ale když budu mít o čem, určitě chci psát dál.

Jakub Vrána, Ze zákulisí, 17.2.2006, diskuse: 34 (nové: 27) - vložit příspěvek

MySQL typ timestamp

MySQL před verzí 5 sice nemá triggery, ale první sloupec typu timestamp v tabulce se sám aktualizuje, ať chceme nebo ne. Jeho nejčastější použití proto asi bude pro uchování času poslední modifikace záznamu. Před verzí 4.1 měl tento typ formát YYYYMMDDhhmmss a dala se určit jeho přesnost, v novějších verzích má stejný formát jako datetime a navíc se dá ovlivnit, jestli se má nastavovat na aktuální čas zvlášť při vytváření a při modifikaci.

Použití tohoto typu sloupce může kód zjednodušit a sjednotit, protože při každém UPDATE nemusíme myslet na aktualizaci tohoto sloupce. Jeho použití je ale určitě na vlastní riziko, protože např. hromadné aktualizace všech záznamů v tabulce tento sloupec samozřejmě také nastaví na aktuální čas a tím ho pro naše potřeby mohou znehodnotit. Pokud se sloupec aktualizovat nemá, dá se použít následující konstrukce:

<?php
mysql_query("UPDATE clanky SET perex = CONCAT('<p>', perex, '</p>'), zmeneno = zmeneno WHERE perex NOT LIKE '<p>%'");
?>
Jakub Vrána, Výuka, 15.2.2006, diskuse: 4 (nové: 4) - vložit příspěvek

Výpis času podle časového pásma

Jedna z výhod malého českého prostředí je v tom, že se rozkládá pouze v jednom časovém pásmu. Na webhostingu tedy může být časové pásmo nastaveno na CET, ve skriptech se nemusíme o nic starat a všem lidem se čas bude zobrazovat správně. Pokud se na stránku náhodou podívá někdo ze vzdáleného zahraničí, tak zobrazovaný čas pochopí jako místní čas serveru a na svůj čas si ho dokáže převést.

Problém ale nastává u serverů, kde není na první pohled patrné, do jakého časového pásma patří. Když je na anglicky psaném serveru uvedeno, že článek vyšel ve 14:00, můžeme o převodu na náš čas jen spekulovat. Na někoho může působit divně i to, že když příspěvek do diskuse vložil v 18:00, tak se u něj zobrazuje, že ho vložil ve 14:00. Pokud tedy z kontextu serveru není patrné, v jakém leží časovém pásmu, je slušné to někam uvést (pro zdůraznění světovosti za všechny časy nebo decentně někam do informací o serveru).

Ideální by bylo časové pásmo nastavovat podle přání klienta. Prohlížeče ale informaci o svém časovém pásmu bohužel neposílají a co hůř - ve standardu na to ani není vyhrazena žádná hlavička. Jedinou možností tak zůstává časové pásmo odhadnout z IP adresy nebo ho nechat uživatele zvolit.

Nastavení časového pásma skriptů od PHP 5.1 zajišťuje funkce date_default_timezone_set nebo konfigurační direktiva date.timezone, ve starších verzích k tomu slouží nastavení proměnné prostředí TZ funkcí putenv. MySQL časová pásma podporuje od verze 4.1. V nižších verzích je potřeba dát pozor na současné používání funkcí typu NOW spolu s přímým zadáním času. Hodit by se mohla funkce UNIX_TIMESTAMP, která vždy vrací počet vteřin od půlnoci 1.1.1970 GMT.

Jakub Vrána, Seznámení s oblastí, 13.2.2006, diskuse: 11 (nové: 11) - vložit příspěvek

Umístění přihlašovacích údajů databáze

Lidi se mě často ptají, kam je vhodné ukládat přihlašovací údaje pro přístup k databázi. Osobně mi nedělá potíže je uložit přímo do PHP kódu a pokud je server správně zabezpečený, neměl by se k nim nikdo dostat. Pokud mají být zdrojáky volně přístupné, je nutné buď soubor s přihlašovacími údaji ošetřovat odlišně nebo je nutné přihlašovací údaje uložit jinam.

Pro uložení přihlašovacích údajů se dají použít direktivy mysql.default_user a mysql.default_password vložené buď přímo do konfiguračního souboru Apache (takže tento soubor bude muset být běžným uživatelům nečitelný a změnu přihlašovacích údajů bude muset dělat administrátor) nebo do souboru z něj vloženého. Pokud případný restart Apache bude provádět root, může tento soubor patřit běžnému uživateli a pro všechny ostatní být nečitelný. To mi přijde jako nejlepší řešení.

Jakub Vrána, Řešení problému, 10.2.2006, diskuse: 3 (nové: 3) - vložit příspěvek

Starší články naleznete v archivu.

© 2005-2006 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=On, magic_quotes_sybase=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE.