Interval.cz
Vyh╛adßvaΦ v PHP a MySQL

Na strßnkach m⌠₧ete pomerne Φasto natrafi¥ na vyh╛adßvaΦe, ktorΘ vyh╛adßvaj· z databßzi urΦitΘ Φlßnky alebo adresy. V tejto minisΘrii Φlßnkov sa dozviete, ako si spravi¥ tak² jednoduch² vyh╛adßvaΦ, ktor² pri sprßvnom vyu₧itφ kaskßdov²ch Üt²lov m⌠₧ete pomerne jednoducho vlo₧i¥ do hotovej strßnky.

Celß sΘria sa skladß z troch Φlßnkov, v prvom si vytvorφme vyh╛adßvaΦ s jeho zßkladn²mi prvkami. NßroΦnejÜφ si urΦite radi preΦφtaj· i druh· Φas¥, v ktorej popφÜem tvorbu odkazov na vÜetky strany naraz (1, 2, 3, ... 15), formulßr na napφsanie Φφsla strany a dodatoΦn² formulßr pre vyh╛adßvanie. V tretej Φasti si vytvorφme Ütatistiku vyh╛adßvanφ, kde budete ma¥ preh╛ad, akΘ slovß s· najΦastejÜie vyh╛adßvanΘ a tak ∩alej.

Ako to funguje

Vyh╛adßvaΦe nevypisuj· vÜetky nßjdenΘ ·daje na jednu stranu. Pokia╛ ich je ve╛a, strßnka by sa naΦφtala ve╛mi pomaly. Preto ich vypφÜe naprφklad po desiatich odkazoch a rozdelφ na strany. Ukß₧e vßm poΦet strßn a Φφslo strany, na ktorej sa prßve nachßdzate. Tak isto vßm ukß₧e poΦet nßjden²ch zßznamov a pokia╛ ich je viac ako dovo╛uje zobrazi¥ na jednej strane, tak vytvorφ odkaz na zobrazenie ∩alÜφch alebo predoÜl²ch strßn. V naÜom vyh╛adßvaΦi si okrem tohto m⌠₧ete priamo klikn·¥ na Φφslo strßnky, na ktor· chcete φs¥. K dispozφcii mßte formulßr, kde si Φφslo strany m⌠₧ete napφsa¥ a prejs¥ na ≥u. DodatoΦn² formulßr bude umo₧≥ova¥ v²ber databßzy alebo niektorej podmienky, pre ktor· sa bude vyh╛adßva¥ a v²ber polo₧ky, pod╛a ktorej bud· v²sledky zoradenΘ.

Pre preh╛ad si najprv struΦne opφÜeme vÜetky strßnky:

  • db.php û pripojenie k databßze
  • vytvor_tabulku.php û vytvorenie sk·Üobnej tabu╛ky na ·daje pre tento prφklad
  • vyhladavac.php û samotn² vyh╛adßvaΦ

Vytvorenie databßzovej tabu╛ky (vytvor_tabulku.php)

Vyh╛adßva¥ m⌠₧ete prakticky Φoko╛vek. PodstatnΘ je, aby sa to nachßdzalo v databßze. Pre nßÜ vyh╛adßvaΦ m⌠₧eme pou₧i¥ naprφklad vyh╛adßvanie internetov²ch strßnok. Preto si vytvorφme jednu jednoduch· tabu╛ku. Tabu╛ka bude obsahova¥ polo₧ky:

  • ID û identifikaΦnΘ Φφslo strßnky
  • Nazov û nßzov strßnky
  • URL û adresa strßnky
  • Popis û popis strßnky
  • Kde û krajina (napr. sk û Slovensko, cz û ╚eskß republika)
  • Datum û kedy bola strßnka pridanß do databßzy

Primßrnym k╛·Φom je ID, ktorΘ je pri ka₧dej strßnke v databßze rozdielne. Aby ste ho v₧dy nemuseli zadßva¥, m⌠₧e obsahova¥ hodnotu auto_increment, ktorß ho pri ka₧dom novom zßzname automaticky zv²Üi o 1. Text, ktor² sa zadß do vyh╛adßvacieho formulßra sa bude vyh╛adßva¥ v polo₧kßch Nazov a Popis. EÜte raz pripomφnam, ₧e pre vyh╛adßvaΦ m⌠₧ete vytvori¥ ak·ko╛vek tabu╛ku a m⌠₧ete vyh╛adßva¥ akΘko╛vek ·daje. Tßto tabu╛ka sl·₧i len pre ukß₧ku a lepÜie pochopenie tohto prφkladu.

require "db.php"; // otvorφ databßzu
$vytvor_tabulku = MySQL_Query("CREATE TABLE vyhladavac(
ID int DEFAULT '0' NOT NULL auto_increment,
Nazov varchar(100),
URL varchar(255),
Popis varchar(255),
Kde varchar(3),
Datum datetime,
PRIMARY KEY(ID))") or die("Tabulku sa nepodarilo vytvori¥"); // vytvorφ tabu╛ku

S·bor db.php obsahuje ·daje pre pripojenie k databßzi. Tieto ·daje treba zmeni¥ pod╛a vlastn²ch potrieb:

$server = ôlocalhostô; // meno serveru
$login = ôô; // prihlasovacie meno
$heslo = ôô; // heslo
$databaza = ôtestô; // nßzov databßze
MySQL_Connect($server, $login, $heslo)
or die(ôNepodarilo sa pripoji¥ k databßzeö); // pripojenie k databßze
MySQL_Select_DB($databaza)
or die(ôNepodarilo sa otvori¥ databßzuô); // v²ber databßze

Do databßzy vlo₧φme nejakΘ ·daje, tie tu vypisova¥ nebudem, zßle₧φ len na vßs, Φo do nej vlo₧φte. M⌠₧em vÜak predvies¥ prφklad:

INSERT INTO vyhladavac VALUES(æÆ, æInterval.czÆ, æhttp://www.interval.czÆ, æProgramovanie, grafika, tvorba strßnokàÆ, æczÆ, æ2002-08-29 17:32:15Æ);

V naÜom vyh╛adßvaΦi sa formulßr na h╛adanie bude objavova¥ na ka₧dej strane. Takto sa dß jednoducho zaΦa¥ novΘ h╛adanie. Pou₧itΘ kaskßdovΘ Üt²ly tu opisova¥ nebudem, lepÜie si ich m⌠₧ete pozrie¥ na strßnke vyhladavac.php. Ke∩₧e ich nieje a₧ tak ve╛a, tak nie s· oddelenΘ do samostatnΘho s·boru. Ako som spomφnal, zßznamy sa bud· vypisova¥ po desiatich odkazoch. Tento efekt dosiahneme prφkazom LIMIT, ktor² sa vpisuje do Φasti SELECT * FROM... LIMIT $od, $do. Limit je obmedzen² dvoma Φφslami, ktorΘ sa uchovßvaj· v premennej. Tieto premennΘ ($od, $do) sa menia pri prechode na ka₧d· nßjden· stranu. Preto sme v skripte vytvorili podmienky, ktorΘ urΦuj· ve╛kos¥ t²chto premenn²ch. Ich hodnota sa urΦuje na zßklade hodnoty, ktor· obsahuje premennß $strana. Na prvej nßjdenej strane t·to premenn· sami vytvorφme s hodnotou 1. Je vytvorenß podmienka:

if($strana==1 && $pocet_stran>1):
$od = "0";
$do = "10";

V premennej $pocet_stran je uchovanß hodnota poΦtu strßn. Tßto podmienka platφ len v prφpade, ₧e strßn je viacej. Pokia╛ je strana len jedna, znamenß to, ₧e poΦet nßjden²ch zßznamov m⌠₧e by¥ menÜφ ako 10. V takomto prφpade nem⌠₧eme necha¥ vypφsa¥ desa¥ zßznamov a vytvorφme ∩alÜiu podmienku, ktorß zaistφ ich limit:

elseif($pocet_stran==1 && $strana==1):
$od = "0";
$do = $pocet;

V premennej $pocet pritom uchovßvame celkov² poΦet nßjden²ch zßznamov. Limit nßm zaruΦφ vypφsanie nßjden²ch zßznamov od 0 po ich celkov² poΦet, ktor² je pri tejto podmienke menÜφ alebo rovn² 10. Na ∩alÜej strane u₧ premennß $strana nesie hodnotu 2 alebo viacej. NaÜa ∩alÜia podmienka preto vyzerß takto:

elseif($strana<=$pocet_stran && $zvysok==0):
$od = $strana*10-10;
$do = $strana*10;

Premenn· $zvysok vypoΦφtame $zvysok = $pocet%10 a pokia╛ celkov² poΦet nßjden²ch zßznamov mß pri delenφ desiatimi nejak² zvyÜok, tak tßto premennß ho obsahuje. Je to samozrejme i v prφpade, ₧e je zvyÜok nula. Tßto podmienka vychßdza z toho, ₧e sme na ktorejko╛vek strane, ale zvyÜok sa musφ rovna¥ nule. Tak ako na prvej strane, tak ani na poslednej nem⌠₧me necha¥ vypφsa¥ desa¥ zßznamov, ke∩ ich zostßva naprφklad len devΣ¥. Pri nulovom zvyÜku vÜak m⌠₧eme. Premennß $strana obsahuje hodnotu, ktorß sa vynßsobφ desiatimi. Tak zφskavame limit $do. Samozrejme, potom $od musφ by¥ $do-10, ke∩₧e vyh╛adßvame zßznamy po desiatich. Predposlednß podmienka vyzerß takto:

elseif($strana<$pocet_stran && $zvysok!=0):
$od = $strana*10-10;
$do = $strana*10;

Je to prakticky ve╛mi podobnΘ, len₧e tu sa zvyÜok nerovnß nule a strana, na ktorej sa nachßdzate nesmie by¥ poslednß. Poslednß podmienka je urΦenß pre posledn· stranu pri nenulovom zvyÜku:

elseif($strana==$pocet_stran && $zvysok!=0):
$od = $strana*10-10;
$do = $strana*10-BCSub(10, $zvysok);

Funkcia BCSub() odrßta druhΘ Φφslo od prvΘho a vrßti v²sledn· hodnotu. V tomto prφpade sme ju vyu₧ili na vypoΦφtanie poΦtu nßjden²ch zßznamov odΦφtanφm zvyÜku od desiatich.

Funkciu MySQL_Query v naÜom vyh╛adßvaΦi pou₧ijeme pre vyh╛adßvanie a₧ dva krßt. Prv² krßt iba zistφme poΦet nßjden²ch zßznamov ($pocet). Z toho odvodφme poΦet strßn, zvyÜok a tie₧ limit. Druh² krßt u₧ vyh╛adßvame konkrΘtne zßznamy v rozsahu. Pokia╛ je $pocet vΣΦÜφ ako nula, vypφÜu sa nßjdenΘ ·daje. Potom je potrebnΘ vytvori¥ odkazy na ostatnΘ strany. V tejto Φasti si popφÜeme iba tvorbu odkazov na ∩alÜiu a predchßdzaj·cu stranu. Odkaz na ∩alÜiu stranu zobrazuje aj poΦet zßznamov, ktorΘ nßs na druhej strane Φakaj·. Na poslednej ich m⌠₧e by¥ menej ako desa¥. V odkaze musφme prenßÜa¥ vÜetky ·daje, ktorΘ s· vyplnenΘ vo formulßri. Musia obsahova¥ nßzvy polφ vo formulßri a tie₧ ich hodnoty. Cel² odkaz bude vyzera¥ naprφklad takto: vyhladavac.php?strana=$kolko_stran&slovo=$slovo.... V ∩alÜom Φlßnku bude ·dajov pre vyh╛adßvanie viacej. Vyh╛adßvaΦ m⌠₧e robi¥ äproblΘmyô v prφpade, ₧e zabudnete do odkazu napφsa¥ vÜetky premennΘ s ich hodnotami. Musia by¥ napφsanΘ a₧ dva krßt. Prv² krßt v odkaze ä╧alÜie zßznamyô a druh² krßt v odkaze äPredchßdzaj·ce zßznamyô, ke∩₧e sa chceme vrßti¥ i spΣ¥.

Cel² skript vyzerß takto:

<!-- zaΦiatok formulßru -->
<form action="vyhladavac.php" method="get">
<div class="normal">
<!-- Φo budeme vyh╛adßva¥ -->
Vyh╛ada¥:
<input name="slovo" class="textinput">
&nbsp;
<!-- potvrdφme vyh╛adßvanie -->
<button type="submit" class="button">H╛adaj</button>
</div>
</form>
<!-- koniec formulßru -->
<hr size="1" color="black">
<!-- Φiara, ktorß odde╛uje formulßr od nßjden²ch zßznamov -->

<?php
if($slovo != "" && $slovo != " "): // vyh╛adßva¥ sa zaΦne pod podmienkou, ₧e existuje slovo pre vyh╛adßvanie a nesie aj nejakΘ rozumn· hodnotu
   require "db.php" // pripojφme sa k databßze

   $result = mysql_query("SELECT * FROM vyhladavac WHERE (Nazov like '%$slovo%') OR (Popis like '%$slovo%')"); // zistφme poΦet nßjden²ch zßznamov
   $pocet = mysql_NumRows($result); // poΦet uchovßvame v premennej
   $zvysok = $pocet%10; // zistφme zvyÜok pri delenφ desiatimi

   // vypoΦφtame celkov² poΦet strßn
   if($zvysok!=0): $pocet_stran = BCDiv($pocet, 10)+1;
   else: $pocet_stran = BCDiv($pocet, 10);
   endif;

   if(IsSet($strana) && $strana>$pocet_stran): die("Tßto strana neexistuje!"); // ak sme sa dostali na stranu vΣΦÜiu, ako je mo₧nΘ
endif;

if(Empty($strana) || !$strana) $strana = 1; // ak neexistuje premennß $strana, tak ju vytvorφme a dßme jej hodnotu 1

   if($pocet > 0) echo "<div align=\"center\" class=\"normal\">($strana/$pocet_stran)</div>";
   // ak s· nejakΘ nßjdenΘ zßznamy, tak pre orientßciu vypφÜeme Φφslo strany, na ktorej sa nachßdzame a celkov² poΦet strßn

   echo "<div class=\"normal\">H╛adßm slovo \"$slovo\"</div><br>";
   // napφÜeme nßzov h╛adanΘho slova

   echo "<div class=\"normal\">PoΦet nßjden²ch zßznamov: $pocet</div><br><br>";
   // vypφÜeme poΦet nßjden²ch zßznamov

   if($pocet > 0): // ak je poΦet vΣΦÜφ ako nula, tak ideme ∩alej

      if($strana==1 && $pocet_stran>1): $od = 0;
      $do = 10;
      // ak $strana je prßzdna a poΦet strßn je vΣΦÜφ ako 1

   elseif($pocet_stran==1 && $strana==1):
      $od = 0;
      $do = $pocet;
      // ak je len jedna strana a na nej sa prßve nachßdzame

   elseif($strana<=$pocet_stran && $zvysok==0):
      $od = $strana*10-10;
      $do = $strana*10;
      // ak je strana menÜia alebo rovnß poΦtu strßn a zvyÜok je nula

   elseif($strana<$pocet_stran && $zvysok!=0):
      $od = $strana*10-10;
      $do = $strana*10;
      // ak je strana menÜia ako poΦet strßn a zvyÜok sa nerovnß nule

   elseif($strana==$pocet_stran && $zvysok!=0):
      $od = $strana*10-10;
      $do = $strana*10-BCSub(10, $zvysok);
      // ak sme na poslednej strane a zvyÜok sa nerovnß nule

   endif; // koniec podmienky

   $vysledok = mysql_query("SELECT * FROM vyhladavac WHERE (Nazov like '%$slovo%') OR (Popis like '%$slovo%') LIMIT $od,$do");
   // zφskali sme potrebnΘ ·daje z databßzi

   $novy_pocet = BCSub($do, $od);
   // vypoΦφtame nov² poΦet, pod╛a ktorΘho budeme vypisova¥ nßjdenΘ zßznamy (odΦφtavame $do - $od)

   echo "<table>";
   // vytvorφme zaΦiatok tabu╛ky

   for($i=0;$i<$novy_pocet;$i++):

      $nazov = MySQL_Result($vysledok, $i, "Nazov");
      $url = MySQL_Result($vysledok, $i, "URL");
      $popis = MySQL_Result($vysledok, $i, "Popis");

      echo "<tr><td><div class=\"big\"><a href=\"$url\"><b>$nazov</b></a></div></td></tr>";
      echo "<tr><td><div class=\"small\"><a href=\"$url\"><i>$url</i></a></div></td></tr>";
      echo "<tr><td width=\"700\"><div class=\"normal\">$popis</div></td></tr>";
      echo "<tr><td height=\"10\"></td></tr>";

      // vypφsali sme zßznamy do po₧adovanΘho formßtu

   endfor;

   echo "</table>"; // vytvorφme koniec tabu╛ky

endif; // koniec podmienky

if($strana==1): $kolko_stran = 2; // ak· hodnotu bude ma¥ ∩alÜia strana?
else: $kolko_stran = $strana+1;
endif;

$kolko_stran2 = $strana-1; // ak· hodnotu mala predchßdzaj·ca strana?

// vypoΦφtame, ko╛ko odkazov bude na ∩alÜej strane (m⌠₧e ich by¥ napr. iba 6)
$odkaz2 = $strana*10;
$odkaz = BCSub($pocet, $odkaz2);
if($odkaz>10) $odkaz=10;

   if($pocet_stran>1 && $strana<$pocet_stran):
      echo "<br><br><div align=\"right\" class=\"normal\"><a href=\"vyhladavac.php?strana=$kolko_stran&slovo=$slovo\">╧alÜie odkazy ($odkaz)</a></div>";
   endif;

   if($strana>1):
      echo "<div align=\"left\" class=\"normal\"><a href=\"vyhladavac.php?strana=$kolko_stran2&slovo=$slovo\">Predchßdzaj·ce odkazy (10)</a></div>";
   endif;

endif; // koniec ·plne prvej podmienky
?>

Pokia╛ zmenφte vÜetky potrebnΘ ·daje, tak vßm vyh╛adßvaΦ bude spo╛ahlivo fungova¥. Je to pomerne r²chle a jednoduchΘ. Netreba robi¥ ₧iadne Üpecißlne ·pravy so strßnkou, staΦφ len, ke∩ do nej vlo₧φte skript so zmenami. V ∩alÜom Φlßnku si vytvorφme zdokonalen² vyh╛adßvaΦ s vΣΦÜφmi mo₧nos¥ami. Ak vßm postaΦφ i prvß Φas¥, tak si ju m⌠₧ete stiahnu¥ vrßtane kaskßdov²ch Üt²lov.



Michal èustek (23.10. 2002)

Redakce Interval.cz |  Inzerce na Interval.cz |  Hledßme novΘ autory ISSN 1212-8651 
 ⌐ Zoner software, s.r.o., vÜechna prßva vyhrazena, tento server dodr₧uje prßvnφ p°edpisy o ochran∞ osobnφch ·daj∙.