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 != "/") {
$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 action=szukarka.php method=post>
Szukaj:<INPUT 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. Powrót";
} else {
$trafienia = array_unique($trafienia);
sort($trafienia);
foreach($trafienia as $pojedyncze) {
echo $pojedyncze .'';
}
}
} else {
echo "Przecież chciałeś czegoś szukać! Powrót";
} |
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ć.