MENU

W│asna wyszukiwarka

Ka┐dy rozbudowany i profesjonalny serwis posiada, a przynajmniej powinien posiadaµ w│asn▒ wyszukiwarkΩ. Jest to rozwi▒zanie niezwykle u┐yteczne dla u┐ytkownika, kt≤remu zalezy na czasie. Jak wiadomo w Polsce Internet jest wci▒┐ drogi, a wiΩkszo╢µ internaut≤w │▒czy siΩ przy pomocy modemu. Impulsy lec▒ odwiedzaj▒cy wci▒┐ nie znalaz│ tego co go interesuje. Wyszukiwarka czy mo┐e przeszukiwarka naszej strony pozwoli mu szybko odnale╝µ potrzebne informacje. Administrator za╢ nie musi martwiµ siΩ spadaj▒c▒ ogl▒dalno╢ci▒, poniewa┐ ludzie zapamiΩtaj▒ sobie, ┐e na tym serwisie dostΩp do informacji jest bardzo │atwy.
Te naprawdΩ rozbudowane wyszukiwarki korzystaj▒ z baz danych, a kto╢ kto dopiero zaczyna przewa┐nie nie ma dostΩpu do tego typu rozwi▒za± lub po prostu nie staµ go na nie. Dlatego opisany ni┐ej skrypt bazuje na plikach, nie wymaga znajomo╢ci obs│ugi bazy.
Og≤lnie rzecz bior▒c skrypcik przeszukuje ca│e drzewko katalog≤w i sprawdza czy w kt≤rym╢ z plik≤w nie ma wyszukiwanego ci▒gu znak≤w. Oczywi╢cie pliki multimedialne (graficzne, d╝wiΩkowe, filmowe) nie s▒ sprawdzane.
Na pocz▒tek dwie funkcje, na kt≤rych wszystko siΩ opiera:
function drzewko($folder) {
  global $pliki;
  if($folder[strlen($folder)-1] != "/") {
    $folder .= "/";
  }
  $id_f = opendir($folder);
  if($id_f) {
    while($plik = readdir($id_f)) {
      if($plik == '.' || $plik == '..') {
        continue;
      }
      if(is_dir($folder . $plik)) {
        drzewko($folder . $plik);
      } else {
        $pliki[] = $folder . $plik;
      }
    }
    closedir($id_f);
  }
  return $pliki;
}

function czytelne($spis) {
  $rozszerzenie[] = "txt";
  $rozszerzenie[] = "dat";
  $rozszerzenie[] = "php";
  $rozszerzenie[] = "php3";
  $rozszerzenie[] = "phtml";
  $rozszerzenie[] = "htm";
  $rozszerzenie[] = "html";
  foreach($rozszerzenie as $roz) {
    $dl_roz = strlen($roz);
    foreach($spis as $plik) {
      if(substr($plik, -$dl_roz) == $roz) {
        $wynik[] = $plik;
      }
    }
  }
  return $wynik;
}

Od pocz▒tku: s│owo kluczowe function s│u┐y do deklarowania funkcji, po nim nastΩpuje nazwa wraz z nawiasami okr▒g│ymi, wewn▒trz kt≤rych mog▒, chocia┐ nie musz▒ pojawiµ siΩ parametry. Funkcja drzewko() jest funkcj▒ rekurencyjn▒, czyli tak▒ kt≤ra wywo│uja sama siebie. Przeszukuje ona podany folder i wszystkie jego podfoldery, a tak┐e podfoldery podfolder≤w itd. Najpierw sprawdza czy na ko±cu jest slash, je╢li nie to go dopisuje. Takie zabezpieczenie, ┐eby nie powstawa│y dziwne nazwy folder≤w, a tym samym, ┐eby ten skrypt przeszuka│ ca│e drzewko. NastΩpnie podany katalog jest otwierany i sprawdzane s▒ wszystkie jego elementy. Je╢li trafi na katalog to jest on sprawdzany w taki sam spos≤b. W przeciwnym wypadku aktualnie sprawdzany element dopisywany jest do tablicy, w kt≤rej przechowywane s▒ pliki w celu p≤╝niejszego wykorzystania. Tak wiΩc wynikiem dzia│ania funkcji drzewko jest tablica zawieraj▒ca spis wszystkich plik≤w.
Ta lista plik≤w nastΩpnie jest weryfikowana. Wewn▒trz funkcji czytelne() deklarowana jest tablica zawieraj▒ca rozszerzenia plik≤w, kt≤re maj▒ byµ przeszukiwane. Foreach() to specyficzna pΩtla pozwalaj▒ca sprawdziµ ka┐dy element tablicy. Tak wiΩc w t│umaczeniu na normalny jΩzyk kolejne linijki to: sprawd╝ ka┐dy element tablicy $spis czy przypadkiem nie ko±czy siΩ kt≤rym╢ z rozszerze±. Wykorzystane zosta│y dwie funkcje operuj▒ce na stringach, czyli strlen() oraz substr(). Pierwsza sprawdza d│ugo╢µ podanego ci▒gu znak≤w, a druga czy ostatnie znaki stringu $plik s▒ takie same jak rozszerzenie. O tym, ┐e ma sprawdzaµ ostatnie znaki informuje znak minus umieszczony przed d│ugo╢ci▒ rozszerzenia.
Mamy dwie funkcje, ale jeszcze nic nie zrobili╢my. Za│≤┐my, ┐e nasz skrypy to plik szukarka.php, a plik strony g│≤wnej to index.html. Na stronie g│≤wnej umieszczamy formularz.

<form method="post" action="szukarka.php">
Szukaj:<input type="text" name="szukane">
<input type="submit" value="Go!">
</form>

Pole uzupe│niane przez u┐ytkownika nazywa siΩ "szukane", w PHP nazwa pola staje siΩ nazw▒ zmiennej.

if(isset($szukane) && $szukane != '') {

  $szukane = ereg_replace("[\*\.\$/]", "", $szukane);
  $szukane_slowa = split("\ ", $szukane);
  array_unshift($szukane_slowa, $szukane);
  $ile_slow = count($szukane_slowa);
  unset($szukane);

  $pliki = drzewko(".");
  $czytelne = czytelne($pliki);
  unset($pliki);
  sort($czytelne);

  foreach($czytelne as $plik) {
    $id_pliku = fopen($plik, "r");
    $zawartosc = fread($id_pliku, filesize($plik));
      for($i=0; $i < $ile_slow; $i++) {
        if(ereg($szukane_slowa[$i], $zawartosc)) {
          $trafienia[] = $folder . $plik;
        }
      }
    fclose($id_pliku);
  }

  if(!isset($trafienia)) {
    echo "Niestety nie znaleziono nic co by pasowa│o 
do twojego zapytania<br><a
href=\"javascript:history.back()\">Powr≤t</a>"; } else { $trafienia = array_unique($trafienia); sort($trafienia); foreach($trafienia as $pojedyncze) { echo "<a href=\"" . $pojedyncze . "\">" . $pojedyncze .
"</a><br>"; } } } else { echo "<center><h2>Przecie┐ chcia│e╢ czego╢ szukaµ
!</h2><a
href=\"javascript:history.back()\">Powr≤t</a></center>"; }

To w│a╢ciwa czΩ╢µ naszego skryptu. Na pocz▒tek sprawdzamy czy co╢ w og≤le zosta│o wpisane, je╢li nie, generujemy odpowiedni komunikat.
Na pocz▒tek kilka operacji na podanym ci▒gu znak≤w. Usuwane s▒ znaki specjalne. Ja wyrzuci│em tylko gwiazdkΩ, kropkΩ, znak dolara i slash. P≤╝niej wyra┐enie "ciΩte" jest na s│owa przy pomocy funkcji split(). Jednak ┐eby nie uciek│o nam ca│e wyra┐enie dorzucamy je na pocz▒tek tablicy, funkcja array_unshift(). W tym miejscu uwaga, zosta│a ona dodana dopiero w wersji PHP 4.0, wiΩc je╢li na serwerze jest zainstalowana starsza wersja pojawi siΩ b│▒d, a ca│y skrypt nie bΩdzie dzia│a│. P≤╝niej zliczna jest ilo╢µ element≤w tablicy $szukane_slowa, a pierwotny ci▒g znak≤w jest usuwany z pamiΩci. NastΩpnie zczytywane s▒ wszystkie pliki z folderu w kt≤rym znajduje siΩ nasz skrypt. Je╢li podamy kt≤ry╢ z podfolder≤w przy wywo│aniu to zostanie sprawdzony tylko on. Sprawdzamy, kt≤re pliki nadaj▒ siΩ do naszych cel≤w i usuwamy tablicΩ $pliki.
Teraz najwa┐niejsza czΩ╢µ. Znowu wykorzystujemy pΩtlΩ foreach(). Sprawdzamy ka┐dy plik czy znajduje siΩ w nim szukany ci▒g znak≤w. W tym celu otwieramy plik i odczytujemy jego zawarto╢µ, kt≤ra jest sprawdzana. Je╢li znajdziemy to czego szukamy, to plik jest dopisywany do tablicy $trafienia. Je╢li w ┐adnym pliku nie bΩdzie szukanego ci▒gu znak≤w tablica $trafienia nie bΩdzie istnieµ. Ten fakt wykorzystujemy do wygenerowania ostatecznych wynik≤w. Po prostu wypisujemy zawarto╢µ tablicy i tworzymy linki do poszczeg≤lnych plik≤w.
To wszystko. Mam jednak tylko jedn▒ uwagΩ. Je╢li liczba przeszukiwanych plik≤w bΩdzie du┐a, czas oczekiwana na wynik mo┐e siΩ wyd│u┐yµ.

 

Autor:
Marcin Zbijowski 
zbijowski@webhelp.pl

http://jednostkaspecjalna.npl.pl

 
 

Contents copyright © 2000 - 2001, Krzysztof Dziewo±ski. All rights reserved.