Jak na vlastní katalog stránek v PHP – pokročilé hledání

26. března 2001

V předchozím článku jsme se podívali na základní jednoduché vyhledávání nad databází odkazů. Dnes se zaměříme na jistě zajímavější část, a to na vyhledávání pokročilé. Kromě možnosti vyhledání přesné fráze (jak tomu bylo v podstatě u základního vyhledání), budeme nyní implementovat například logické AND a OR nad všemi zadanými řetězci. Uživateli také nabídneme setřídění výstupu dle různých kritérií.

Formulář

Nejprve si zadefinujme formulář, jehož kód bude umístěn na začátku skriptu advanced.php:

<FROM METHOD=“get“ ACTION=“advanced.php“>
Zadejte slova oddělená mezerou:<BR>
<INPUT TYPE=“text“ NAME=“retezec“ SIZE=40 MAXLENGTH=120><BR>
<INPUT TYPE=“radio“ NAME=“typ“ VALUE=1 CHECKED> přesná fráze<BR>
<INPUT TYPE=“radio“ NAME=“typ“ VALUE=2> obsahuje alespoň jedno ze slov (OR)<BR>
<INPUT TYPE=“radio“ NAME=“typ“ VALUE=3> obsahuje právě všechna slova (AND)<BR>
<INPUT TYPE=“radio“ NAME=“typ“ VALUE=4> hledat URL
– <TT>http://</TT><INPUT TYPE=“text“ NAME=“ret_url“ SIZE=40 MAXLENGTH=80><BR>
<BR>
Výstup setřídit dle:<BR>
<INPUT TYPE=“radio“ NAME=“tridit“ VALUE=1 CHECKED> názvu<BR>
<INPUT TYPE=“radio“ NAME=“tridit“ VALUE=2> kvality<BR>
<INPUT TYPE=“radio“ NAME=“tridit“ VALUE=3> data vložení<BR>
<INPUT TYPE=“submit“ NAME=“akce“ VALUE=“Najdi“>
</FORM>

Ve výsledné stránce bude formulář vypadat nějak takto:

Zadejte slova oddělená mezerou:

přesná fráze
obsahuje alespoň jedno ze slov (OR)
obsahuje právě všechna slova (AND)
hledat URL – http://
Výstup setřídit dle:
názvu
kvality
data vložení

Advanced.php

Tento skript bude mít velmi jednoduchou strukturu. Na jeho začátku se vždy zobrazí formulář a ve zbytku se zobrazí nalezené odkazy. Jak poznáme, že máme hledat a zobrazit odkazy? Jednoduše, prostě tak, že skript byl zavolán s  parametrem AKCE. Struktura tohoto skriptu by mohla být znázorněna takto:

&lt?php
/* nejprve zobrazime formular */
if (($akce) && ($akce == ‚Najdi‘)) {
  /* najdeme odkazy splnujici podminky */
  /* a zobrazime je zde ve forme seznamu */
}
?>

Parametry skriptu

Pokud tedy uživatel v našem katalogu stránek klikne na odkaz [Pokročilé hledání], zavolá se skript advanced.php. Jelikož byl zavolán samostatně, bez jakýchkoliv parametrů (tedy parametr AKCE je nedefinován), zobrazí se pouze formulář a část, která je uvedená v těle příkazu IF se neuplatní. V momentě kdy uživatel v tomto skriptu zadá něco na vyhledání, tak máme v definici formuláře zajištěno, že se skript advanced.php zavolá znovu, a to s definovaným parametrem AKCE.

Kromě parametru AKCE jsou předány ještě parametry další. Parametr RETEZEC (přístupný přes proměnnou $retezec) obsahuje řetězec slov, které uživatel zadal. Dále parametrem TYP rozlišíme, jaký způsob vyhledání uživatel chce. Tímto parametrem v podstatě ovlivníme tvorbu příslušného SQL dotazu. Poslední volbou uživatele je, jakým způsobem chce setřídit výsledek. To zjistíme pomocí hodnoty v parametru TRIDIT. Tolik k popisu jednotlivých parametrů ve formuláři, abychom přesně věděli, k čemu nám budou sloužit.

Zdrojový kód

Nyní je správný čas se podívat na zdrojový text. Vzhledem k tomu, že základní vyhledávání (v našem případě parametr TYP=1, přesná fráze) jsme řešili v minulém článku, dnes se tedy už zaměřím pouze na AND a OR, tzn. když bude na vstupu TYP=2 nebo TYP=3. Nyní budeme programovat tělo příkazu IF (viz struktura skriptu).

/* pokrocile vyhledavani, telo prikazu IF — advanced.php */
/* pro kazdy typ sestrojime odlisny SQL dotaz */
$dotaz = “;
if ($typ == 1) {

  /* resili jsme minule */

}
if (($typ == 2) || ($typ ==3)) {
  /* podle typu si nastavime promennou $spojka */
  if ($typ == 2) {$spojka = ‚OR‘; }
  if ($typ == 3) {$spojka = ‚AND‘; }

  /* ze vstupniho retezce orezeme diakritiku */
  $slova = StrTr ($retezec, „áäčďéěëíňóöřšťúůüýžÁÄČĎÉĚËÍŇÓÖŘŠŤÚŮÜÝŽ“,
    „aacdeeeinoorstuuuyzAACDEEEINOORSTUUUYZ“);

  /* vstupni retezec rozdelime do samostatnych slov */
  $seznam_slov = Split (‚ ‚, $slova);
  $pomocny = „ascii_text LIKE ‚%“.$seznam_slov[0].“‚ „;

  for ($i = 1; $i<Count($seznam_slov); $i++) {
    $pomocny = $pomocny . “ $spojka ascii_text LIKE ‚%“.
    $seznam_slov[$i] . „‚ „;
  }
  $dotaz = „SELECT nazev, popis, url, sekce.nazev AS \“sekce_nazev\“, sekce_id
    FROM odkaz, sekce
    WHERE odkaz.sekce_id = sekce.id
    AND ($pomocny)“;
}
if ($typ == 4) {

  $pomocny = ‚http://‘ . $ret_url;
  $dotaz = „SELECT nazev, popis, url, sekce.nazev AS \“sekce_nazev\“, sekce_id
    FROM odkaz, sekce
    WHERE odkaz.sekce_id = sekce.id
    AND url LIKE ‚$pomocny%‘;
}
/* podle ceho tridit */
$trideni = “;
if ($tridit == 1) {
  $trideni = ‚ ORDER BY odkaz.nazev‘;
}
if ($tridit == 2) {
  $trideni = ‚ORDER BY kvalita_prum‘;
}

/* $trideni pro $tridit==3 nema smysl, nebot se v podstate nejedna o
zadne trideni – bere se primo poradi v tabulce */

$dotaz = $dotaz . $trideni;
mysql_connect(„localhost“);

$odkazy = mysql(„katalog“, $dotaz);
$pocet = mysql_num_rows($odkazy);

/* vypiseme zakladni udaje */
if (($typ == 2) || ($typ == 3)) {
  print „<B> Hledaný výraz: </B> $retezec“;
}
if ($typ == 4) {
  print „<B> Hledané URL: </B> $ret_url“;
}

print „<B> Bylo nalezeno: </B>$pocet záznamů“;
print „<UL>“;
/* vypiseme seznam odkazu, ktere vyhovely hledani */
for ($i = 0; $i<=$pocet; $i++) {
  $nazev = mysql($odkazy, $i, „nazev“);
  $popis = mysql($odkazy, $i, „popis“);
  $url = mysql($odkazy, $i, „url“);
  $sekce = mysql($odkazy, $i, „sekce_nazev“);
  $sekce_id = mysql($odkazy, $i, „sekce_id“);

  print „<LI> <A HREF=\“$url\“>$nazev</A><BR>“;
  print „$popis<BR> <A HREF=\“$url\“>$url</A><BR>“;
  print „sekce: <A HREF=\“$index.php?sekce=$sekce_id\“>~$sekce_nazev</A>“;
}
print „</UL>“;
mysql_close;

Popis kódu

Nejprve musíme sestrojit SQL dotaz. Pro každý typ bude vypadat trochu jinak. Pro rozšířené hledání ze vstupního řetězce nejprve odstraníme diakritiku a pak řetězec rozdělíme na jednotlivá slova (k tomu slouží příkaz split). Po té musíme vygenerovat pomocný řetězec, který např. pro TYP=2 bude vypadat takto: ASCII_TEXT LIKE ‚%slovo1%‘ OR ASCII_TEXT LIKE ‚%slovo2‘ OR …, pro TYP=3 to bude stejné, až na spojku, která zde bude AND. Tento řetězec získáme tak, že do něj nejprve uložíme „ascii_text LIKE ‚%$seznam_slov[0]%'“ a dále k  tomu řetězci postupně přidáváme (to nám zajišťuje cyklus for) další podmínky oddělené logickou spojkou pro každé vyskytující se slovo v původně zadaném řetězci uživatelem.

Pro hledání v URL uživatel vyplní textové pole „ret_url“. Při konstrukci dotazu pro případ TYP=4 bereme v úvahu proměnnou $ret_url a obsah proměnné $retezec ignorujeme.

Jakmile máme pomocný řetězec vygenerován, tak pomocí něj připravíme celý dotaz. Na závěr dotazu ještě přiřetězíme konstrukci ORDER BY …, pokud si uživatel přeje výstup setřídit.

Pak už se připojíme k databázi, provedeme dotaz a vrácené odkazy zobrazíme ve formě seznamu <UL>. Tento úsek je podobný, jako v předchozím díle.

A co bezpečnost?

Máme zde práci z formulářem, je potřeba myslet na to, že nikdy nevíme, kdo k  našim stránkám přistoupí. Zejména je potřeba zkontrolovat, zdali zadaný řetězec uživatelem neobsahuje nějaké nepěkné znaky (např. tagy HTML, apod. – sami si můžete vyzkoušet, co by to se stránkami udělalo ;-). Dále vidíme, že hodnota parametru TYP může nabývat pouze hodnot 1 až 4. Je tedy dobré udělat na začátku test, zdali hodnoty všech parametrů jsou v definovaných rozsazích. Znovu připomínám, že je potřeba během práce s databází ošetřovat všechny chybové stavy. Kvůli větší přehlednosti zde ošetření chyb neuvádím.

Tím máme probrané základní procházení sekcemi, zobrazování odkazů a vyhledávání nad nimi. V příštím díle se podíváme na realizaci přidání odkazu do katalogu uživatelem.

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 *