Программа: Поиск сайта

Программу site-search.php, показанную в примере 19.5, можно использовать как поисковую машину для сайтов от малого до среднего размеров, основанных на файлах. Программа ищет условия поиска (в $_REQUEST['term']) во всех файлах в пределах определенного набора каталогов в корневом каталоге документов. Эти каталоги определяются в $search_dirs. Программа также последовательно заходит в подкаталоги и следует символическим ссылкам, но запоминает, какие файлы и каталоги она просмотрела, так что она не зацикливается.

Если найдены какие-либо страницы, содержащие условия поиска, то она печатает список ссылок на эти страницы, расположенные в соответствии с алфавитным порядком заголовков этих страниц. Если у страницы нет заголовка (между тегами и ), то используется URI страницы относительно корневого документального каталога. Программа ищет условия поиска между тегами и в каждом файле. Если на вашей странице между тегами находится большой объем текста, который вы хотите исключить из поиска, то окружите текст, который следует искать, специальными HTML-коммен-тариями, а затем модифицируйте $body_regex так, чтобы искать эти теги. Например, ваша страница выглядит следующим образом:


// Некоторые HTML-элементы для меню, заголовков и т.


д.

Aliens Invade Earth


by H.G. Wells


Aliens invaded earth today. Uh Oh.


// Продолжение повествования

// Некоторые HTML-элементы для нижних колонтитулов и т. д.


Чтобы сравнивать условия поиска только с названием, автором и с изложением внутри HTML-комментариев, измените $body_regex на:

$body_regex = '#(.*' .
preg_quote($_REQUEST['term'],'#').
'.*)#Sis';

Если вы не хотите, чтобы условия поиска сравнивались с текстом внутри тегов HTML или PHP на вашей странице, то добавьте вызов функции strip_tags() в программу, загружающую содержимое файла для поиска:

// загружаем содержимое файла в переменную $file
$file = strip_tags(join('',file($path)));

Пример 19.5. site-search.php
function pc_search_dir($dir) {
global $body_regex,$title_regex,$seen;
// массив для хранения соответствующих страниц
$pages = array();
// массив для хранения каталогов поиска
$dirs = array();
// отмечаем этот каталог как просмотренный,
// чтобы не просматривать его снова
$seen[realpath($dir)] = true;
// если мы можем получить дескриптор этого каталога
if (is_readable($dir) && ($d = dir($dir))) {
// берем каждое имя файла в каталоге
while (false !== ($f = $d->read())) {
// строим полный путь к файлу
$path = $d->path.'/'.$f;
// если это обычный файл и мы можем прочитать его
if (is_file($path) && is_readable($path)) {
$realpath = realpath($path);
// если мы уже видели этот файл,
if ($seen[$realpath]) {
// то пропускаем его
continue;
} else {
// в противном случае отмечаем его как просмотренный,
// чтобы пропустить его, если придем к нему снова
$seen[$realpath] = true;
}
// загружаем содержимое файла в переменную $file
$file = join('',file($path));
// если условия поиска находятся внутри
// ограничителей body
if (preg_match($body_regex,$file)) {
// конструируем относительный URI файла, удаляя
// документальный корневой каталог из полного пути
$uri = substr_replace($path,'',0,strlen
($_SERVER['DOCUMENT_ROOT']));
// Если страница имеет название, то находим его
if (preg_match('#(.*?)#Sis',$file,$match)) {
// и добавляем название и URI в переменную $pages
array_push($pages,array($uri,$match[1]));
} else {
// в противном случае используем URI
// в качестве названия
array_push($pages,array($uri,$uri));
}
}
} else {
// если элемент каталога – это допустимый подкаталог
if (is_dir($path) && ('.' != $f) && ('..' != $f)) {
// добавляем его к списку каталогов для просмотра
array_push($dirs,$path);
}
}
}
$d->close();
}
/* Просматриваем каждый файл в каждом подкаталоге данного каталога
* и добавляем найденные страницы из этих каталогов
* к переменной $pages.


Просматриваем только подкаталог,
* который мы еще не видели.
*/
foreach ($dirs as $subdir) {
$realdir = realpath($subdir);
if (! $seen[$realdir]) {
$seen[$realdir] = true;
$pages = array_merge($pages,pc_search_dir($subdir));
}
}
return $pages;
}
// вспомогательная функция для сортировки найденных страниц
// в алфавитном порядке их названий
function pc_page_sort($a,$b) {
if ($a[1] == $b[1]) {
return strcmp($a[0],$b[0]);
} else {
return ($a[1] > $b[1]);
}
}
// массив для хранения страниц, соответствующих условиям поиска
$matching_pages = array();
// массив для хранения страниц во время сканирования условий поиска
$seen = array();
// каталоги для поиска ниже корневого документального каталога
$search_dirs = array('sports','movies','food');
// Регулярное выражение для использования в искомых файлах. Модификатор
// шаблона «S» говорит машине PCRE «изучать» regex для большей эффективности.
$body_regex = '#(.*' . preg_quote($_REQUEST['term'],'#').
'.*)#Sis';
// добавляем соответствующие файлы, найденные в каждом каталоге,
// в $matching_pages
foreach ($search_dirs as $dir) {
$matching_pages = array_merge($matching_pages,
pc_search_dir($_SERVER['DOCUMENT_ROOT'].'/'.$dir));
}
if (count($matching_pages)) {
// сортируем найденные страницы по названию
usort($matching_pages,'pc_page_sort');
print '
    ';
    // выводим каждое название со ссылкой на страницу
    foreach ($matching_pages as $k => $v) {
    print sprintf('
  • %s',$v[0],$v[1]);
    }
    print '
';
} else {
print 'No pages found.';
}.



Оцените статью: (0 голосов)
0 5 0

Статьи из раздела PHP на эту тему:
Изменение прав доступа к файлу или его владельца
Копирование и перемещение файла
Обработка всех файлов в каталоге
Обработка всех файлов в каталоге
Получение и установка меток даты/времени файла

Вернуться в раздел: PHP / 19. Каталоги