Nedostupnost připojení k databázi

Školení, která pořádám

V kvalitní webové aplikaci by vždy měla být ošetřena situace, kdy se nepodaří připojit k databázi. Tento stav je nutné důkladně ošetřit, protože bez databáze většina aplikací na ní závislých nebude fungovat ani částečně.

V rámci uživatelské přítulnosti je vhodné chybovou stránku zobrazit v podobném designu jako normální stránky. Osobně si pro vypsání začátku a konce stránky definuji funkce page_header a page_footer, kterým v případě nedostupnosti databáze předám volitelný parametr, podle kterého poznají, že nemají zobrazovat části designu závislé na databázi. Soubor vložený do všech stránek pracujících s databází potom může vypadat takhle:

<?php
if (!mysql_connect() || !mysql_select_db("db")) {
    header("HTTP/1.1 503 Service Unavailable");
    page_header("Nedostupná databáze", "nodb");
    echo "<p>Nepodařilo se připojit k databázi. Zkuste to prosím později nebo nás kontaktujte.</p>\n";
    page_footer("nodb");
    exit;
}
?>

Všimněte si, že se posílá HTTP status 503, který by měl podobně jako ostatní chybové stavy zařídit, že stránku s chybovou hláškou nebudou považovat vyhledávače a cache za tu správnou.

Jakub Vrána, Dobře míněné rady, 29.8.2005, diskuse: 12 (nové: 0)

Diskuse

Jan Bien:

Pane kolego, již delší dobu sleduji Váš vynikající weblog, ale leží mi na srdci jedna otázka. Proč pro výpis hlavičky a patičky používáte funkce globální a nikoliv členské funkce nějakého objektu, pojmenovaného například "document"?

ikona Jakub Vrána OpenID:

Protože jsem nikdy nepochopil, jakou by to pro mě mělo výhodu.

Jan Bien:

Například zde:
<?php
$document
= new Document;
$document->title = 'Kontakty';
$document->description = 'Kontaktovat firmu XY můžete telefonicky, emailem, či osobní návštěvou';
$document->keyword = 'kontakty, XY s.r.o';
$document->section = 3;
$document->render_header();
// ...
$document->render_footer();
unset(
$document);
?>

Výhoda zde je, že proměnné jsou součástí objektu a smím je mohu je používat ve všech členských funkcích.

Kdybych například potřeboval v hlavičce i patičce "vypodmínkovat" nějakou část podle proměnné section, není problém. Při konvenčním způsobu, jaký používáš, bys buďto musel předávat funkci jako parametr, nebo deklarovat jako globální proměno, čímž se ale celá aplikace znepřehledňuje.

ikona Jakub Vrána OpenID:

Jako globální proměnnou určitě ne, ale předat to jako parametry případně pole parametrů kód přeci nijak neznepřehledňuje. Polem parametrů mám na mysli toto:
<?php
page_header
('Kontakty', array(
    'description' => 'Kontaktovat firmu XY můžete telefonicky, emailem, či osobní návštěvou',
    'keyword' => 'kontakty, XY s.r.o',
    'section' => 3)
);
?>

Jan Bien:

Ano, toto řešení lze považovat za celkem OK. Jen to má tu nevýhodu, (ale celkem malou), že bych měl pole předávat hlavičce i patičce (pro případ, že právě například section potřebuji "nahoře" i "dole") či případně dalším funkcím vykreslujícím části stránky.

Jsem velkým příznivcem objektů, právě z důvodů přehlednosti. Ale samozřejmě platí, že solidní vývojář si udrží pořádek i ve funkcích.

zdenek:

velky priznivec objektu, proc on nepouzivat napriklad ... ->set_title() ?? zdravi velky priznivec solidnich vyvojaru 8)

Jan Bien:

On nepoužívat to Vámi uvedené a správné řešení proto, že on zapomněl dodat, že je jen "vývojář amatér".

SQi:

Osobně sám použávam funkce pro výpis hlavičky a patičky jako Jakub Vrána. Co by mi přineslo navíc využít členské funkce nějakého objektu, pojmenovaného například "document"?

anode:

No ja treba podobny objekt vyuzivam i pro zabezpeceni pristupu na stranku. Staci jednou nastavit identifikator prave zobrazene stranky a mam vystarano jak pro zobrazeni hlavicky/paticky, tak i pro zabezpeceni. Mimoto vsechny funkce, ktere nejak pracuji se strankou jako celkem mam tak na jednom miste.

ikona spaze:

Hmm, 503, ze me to nenapadlo driv, dobra poznamka :)

SodaE:

ahoj , nebylo by špatné doplnit že aby se nevypisoval error s mysql tak je dobré udělat error_reporting(0);
a nebo
<?php
if (!@mysql_connect() || !@mysql_select_db("db")) {
/* obsah */
    exit;
}
?>

ikona Jakub Vrána OpenID:

mysql_select_db() chyby negeneruje. Výpis chyb se řídí direktivou display_errors – na ostrém serveru je vhodné tuto direktivu vypnout a naopak zapnout logování chyb. V logu se o chybě připojení potom milerád dozvím.

Vložit komentář

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2018 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=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.