Jazyk PHP nabízí mimo jiné i několik funkcí umožňujících pracovat se soubory ve formátu DBF. Tento formát je podporován v naprosté většině tabukových kalkulátorů a desktopových databází. V prvním dílu tohoto seriálu si ukážeme, v jakých případech se hodí použít formátu DBF, a také si vytvoříme jednoduchý skript umožňující prohlédnout obsah zadaného DBF souboru přes www rozhraní.

Využívat PHP skripty, které přistupují k datům ve formátu DBF, je výhodné v situacích, kdy:

  • potřebujeme publikovat na www stránce data, která vytváříme a uchováváme např. v nějaké desktopové databázi.
  • naše www stránky jsou generovány PHP skriptem z dat uložených v databázi na SQL serveru a rádi bychom zmíněnou databázi (najednou) naplnili daty vytvořenými např. MS Excel.
  • chceme, aby výstupem skriptu, který získává data z SQL serveru, nebyla www stránka, ale soubor v takovém formátu, abychom jej v zápětí mohli dále zpracovat ve spreadsheetu.

V takových případech lze sice v principu využít ODBC rozhraní a ODBC funkcí jazyka PHP, nicméně vhodné ovladače nebývají vždy k dispozici (zejména v prostředí OS Unix/Linux), navíc konfigurace daného ovladače nebývá vždy snadnou záležitostí. Řešení založené na PHP skriptech a formátu DBF je často mnohem jednodušší.
K tomu, abychom mohli volat v našich PHP skriptech funkce dbase_*, je nutné provést jistou úpravu v souboru php.ini (odstraníme středník před direktivou extension=php_dbase.dll) – to v případě, že pracujeme pod Windows. Používáme-li PHP v prostředí OS Unix/Linux, je nutné PHP zkompilovat s příslušnými parametry (více se dozvíte v nápovědě k příslušné verzi PHP).

Jak tedy vytvořit jednoduchý prohlížeč DBF souborů?

Podívejme se nejprve na funkce, které nám PHP k tomuto účelu nabízí:

  • dbase_open(string název_souboru, int režim) otevře databázi uloženou v zadaném souboru. Druhým parametrem určíme způsob otevření – přípustné hodnoty 0, 1, 2 značí (po řadě): pouze pro čtení, pouze pro zápis, pro čtení i zápis. Jestliže se databázi podařilo otevřít, vrací funkce identifikátor databáze, v opačném případě vrací false.
  • dbase_numrecords(int identifikátor_databáze) zjistí počet záznamů v databázi. (Identifikátor získáme pomocí funkce dbase_open.)
  • dbase_numfields(int identifikátor_databáze) vrací počet sloupců v otevřené databázi.
  • dbase_get_record(int identifikátor_databáze, int i) vrací pole (indexované od nuly) odpovídající i-tému záznamu. Toto pole navíc obsahuje asociativní index "deleteted", který určuje, zda je záznam označen jako smazaný. Záznamy jsou ve formátu DBF číslovány od jedné. Obsahuje-li databáze datový typ date, převede jej PHP na typ string. Typ memo není v dbase_* funkcích jazyka PHP podporován.
  • dbase_close(int identifikátor_databáze) uzavře databázový soubor.

Dále též využijeme funkci rtrim(string), která odstraní z pravé strany řetězce netisknutelné znaky. Pro úplnost ještě uveďme seznam dalších dbase_* funkcí jazyka PHP; jejich podrobnější popis se objeví v některém z dalších článků: dbase_get_records_with_names – funkce funguje obdobně jako dbase_get_record s tím rozdílem, že jednotlivé položky ukládá do asociativního pole, jehož indexy odpovídají názvům jednotlivých sloupců, dbase_add_record přidává záznam do databáze, dbase_replace_record změní zadaný záznam, dbase_delete_record označí určený záznam za smazaný, dbase_pack odstraní z databáze záznamy, které byly označeny za smazané, dbase_create vytvoří soubor ve formátu DBF.

Máme tedy už vše připravené k tomu, abychom napsali funkci vypsat_dbf_soubor(string nazev_souboru), která vypíše obsah DBF souboru do přehledné tabulky. Základní myšlenka této funkce je velmi prostá: nejprve otevřeme databázový soubor, poté zjistíme počet záznamů a počet sloupců v tabulce a v jednoduchém for-cyklu získáváme jednotlivé záznamy pomocí funkce dbase_get_record. V případě, že $zaznam["deleted"] ==1 – záznam je tedy označen jako smazaný – použijeme pro příslušný řádek tabulky jiný styl a ve 2. for-cyklu už vypisujeme jednotlivé buňky tabulky, jejichž obsah tvoří jednotlivé prvky pole $zaznam, ze kterých jsme zprava odstranili netisknutelné znaky (mezery). Po ukončení hlavního for-cyklu uzavřeme databázi a vypíšeme informace o počtu záznamů.

<?
function vypsat_dbf_soubor($nazev) {
 
$databaze = @dbase_open("./" . $nazev, 0);
 
//Pokud se nepodařilo otevřít zadaný soubor, vypíšeme chybové hlášení,
if (!$databaze)
  echo "<p class=\"varovani\">\nNepodařilo se otevřít databázový soubor $nazev!\n</p>\n";
 
//jinak zjistíme informace o databázi a začneme generovat tabulku.
else
{
  $pocet_zaznamu = dbase_numrecords($databaze);
  $pocet_sloupcu = dbase_numfields($databaze);
  $pocet_smazanych = 0;
 
  echo "<table border=\"1\" cellpadding=\"3\" cellspacing=\"1\">\n";
 
  for ($i = 1; $i<=$pocet_zaznamu; $i++)
  {
    $zaznam = dbase_get_record($databaze, $i); //…získáváme jednotlivé záznamy…
    //Je-li záznam označen jako smazaný, vypíšeme příslušný řádek tabulky jiným stylem.
    if ($zaznam["deleted"]==1)
    {
      $pocet_smazanych++;
      echo "<tr class=\"smazany\">\n";
    }
    else
      echo "<tr>\n";
 
    //…postupně vypisujeme jednotlivé záznamy…
    for ($j = 0; $j<$pocet_sloupcu; $j++)
      echo " <td>" . rtrim($zaznam[$j]) . "</td>\n";
 
    echo "</tr>\n";
  } //endfor $i
 
  dbase_close($databaze);
 
  if ($pocet_zaznamu == 0)
    echo "<tr><td class=\"varovani\">Databáze neobsahuje žádný záznam.</td></tr>\n";
 
  echo "</table>\n\n";
  echo "<p>Počet záznamů v databázi " . $nazev . ": " . $pocet_zaznamu . ", z toho smazaných: " . $pocet_smazanych . "</p>\n";
} //endif
 

} //end function vypsat_dbf_soubor
?>

Funkce vypsat_dbf_soubor není úplně ideální, pravděpodobně nejvážnějším nedostatekem je, že funkce negeneruje záhlaví tabulky – jazyk PHP totiž nenabízí funkci, která by umožňovala snadno zjistit názvy jednotlivých sloupců. Tato nevýhoda by se dala odstranit např. získáváním prvního záznamu z databáze pomocí funkce dbase_get_record_with_names a následným zjišťováním indexů vráceného asociativního pole pomocí funkce key.

Skipt, který volá tuto funkci a generuje kompletní stránku, je už triviální.

<? include("./dbase1.php") ?>
<html>
 
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1250">
<title>Obsah souboru <? echo $nazev ?></title>
<style>
<!–
h1 { color: #000099; font-family: Times New Roman CE, serif; font-size: 24pt }
p, table { font-family: Arial CE, Helvetica CE, sans-serif; font-size: 8pt }
.varovani { color: #FF0000; font-weight: bold }
.smazany { color: #CCCCCC; font-style: italic }
–>
</style>
</head>
 
<body>
<?
if ($nazev=="")
  echo "<p class=\"varovani\">\nNebyl zadán název souboru.\n</p>";
else
{
  echo "<h1>Obsah souboru $nazev</h1>\n";
  vypsat_dbf_soubor($nazev);
}
?>
</body>
</html>

Zdrojový text souboru dbase1.php, souboru vypsat.php a dvou ukázkových DBF souborů si samozřejmě můžete také stáhnout.

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

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

Žádný příspěvek v diskuzi

Odpovědět