В надежде на то, что кто-нибудь утащит у меня этот скрипт и реализует на его основе тeл.спрaвочник моего города, публикую здесь исходный код.
Распространение - свободное при условии указания индексиpуемой гиперccылки на www.Wgent.com на каждой странице, использующей скрипт.
<?php
require_once("functions.php"); // Это набор моих функций, которые вовсе не сложно переписать самостоятельно
?>
<html><head><META http-equiv=Content-Type content="text/html; charset=windows-1251">
<link rel="stylesheet" type="text/css" href="phone.css" />
<title>Phone Book by Max Brown</title>
</head>
<body>
<?
loadSQL("phone.txt"); die("Телефонная книга загружена. Теперь найдите в коде скрипта эту строчку и закомментируйте её!");
define("NOT_FOUND", "<br /><b>К сожалению, по Вашему запросу ничего не найдено.</b><br /><br />");
define("N_AT_PAGE", 50); // задаём максимальное число записей, выводимых на 1 странице
$q=param("q"); //param() - это моя функция, возвращает параметр, переданный скрипту методом POST или GET.
if(count($q)>1) $q=implode(" ", $q); // На случай запроса вида phone.php?q[]=preved&q[]=medved
$q=trim(stripslashes($q)); // stripslashes убирает инвалидацию апострофов и кавычек: (было "\' стало "'), а trim обрезает пробелы с начала и с конца.
UpLow($q); // Это моя функция перевода в верхний регистр. Она работает с кириллицей надёжнее стандартной strtoupper()
?>
<form method="GET">
<center>
<input name="q" value="<?
echo htmlspecialchars($q); // Во избежание кверилинк-взлома
?>" style="font-size:24px; height:40px; width:600px;" /><input type="submit" style="font-size:24px; height:40px;" value="Показать" />
</center>
</form>
<?
$found="";
if($q) $found=FindPhones($q); // Эта функция описана ниже
echo $found;
if($found==NOT_FOUND){
?>
<br />
<br />Если Вы ищете <b>ПО ИМЕНИ</b>, вводите его в виде: Фамилия Имя Отчество<br />
<small>Имя и отчество можно не указывать. Либо сократить:</small> "Иванов И.И."<br />
<br />При поиске <b>ПО НОМЕРУ</b> учтите, что у нас все номера пятизначные.<br />
<small>Если Вы забыли какую-то цифру, введите вместо неё вопросительный знак.</small><br />
<br />Чтобы найти человека не только по имени, но и <b>ПО АДРЕСУ</b>,<br />
обязательно вводите не только имя и название улицы, но и номер дома.<br /><br />
<? // В конце уже, после результатов, можно вывести и краткий хелповник.
// Потому, что интернетчик, получивший не тот результат, на который рассчитывал, гораздо охотнее читает всякие RTFM, чем просто интернетчик :-)
}//if NOT FOUND
?>
</body>
</html>
<? exit; // ...и на этом завершаем работу
function FindPhones($q){
$qd=preg_replace("/[^0-9?]/si", "", $q); // Убрать всё кроме цифр (Если они есть. Если нет - будет пустая строка. Сейчас это проверим)
if($qd=="") return FindPhonesByName($q); // Если цифр нет вообще, то это было имя человека. Потому что адрес обязан содержать цифры!
//Благодаря оператору return всё остальное идёт как ELSE
// Теперь посмотрим, вдруг нам ввели номер телефона?
// Критерием будем считать наличие ровно 5 цифр, отличных от "48439" и "848439", т.к. 48439 - это код города Обнинска
if( strpos($qd, "848439") === 0 ) $qd=str_replace("848439", "", $qd);
if( strpos($qd, "748439") === 0 ) $qd=str_replace("748439", "", $qd); // для любителей набирать код в международном формате
if( strpos($qd, "48439") === 0 ) $qd=str_replace("48439", "", $qd);
if( strlen($qd)==5 ) return FindPhonesByNumber($qd); // strlen возвращает длину строки. В Обнинске она должна быть равной 5.
// На этом разбор случая "нам ввели номер телефона" завершаем и нам остаётся один-единственный случай: нам ввели адрес
if( preg_match("/[А-ЯЁ]/Usi", $q) && preg_match("/[0-9]/Usi", $q) ) return FindPhonesByAddress($q);
// В случае, когда есть и русские буквы, и цифры - ищем по адресу.
return NOT_FOUND; //Ну, а иначе нам ввели какой-то англоязычный спам, но на всякий случай возвращаем сообщение об ошибке
} //function findphones($q)
function FindPhonesByName($q){
$q=trim( preg_replace("/[^А-ЯЁ-]/Usi", " ", $q) )." "; // Заменяем пробелами всё кроме букв, но пробелы в начале убираем, а в конце добавляем один
while( strpos($q, " ") !== false ) $q=str_replace(" ", " ", $q); // Убираем также двойные пробелы, возможно образовавшиеся в предыдущей строке
$q=str_replace(" ", "% ", $q);
// Преобразование "ФАМИЛ И О" в "ФАМИЛ% И% О%" - напомню, в MySQL знак % означает любую последовательность знаков
$q=trim($q); //Обрезаем крайний справа пробел
$q=str_replace("-% ", "% ", $q); // Недокументированная фича для поиска земляков по городам
$where="CONCAT(name, ' ', birthcity) LIKE '".$q."' ORDER BY BINARY(name)"; // Формируем Where- и order- части MySQL-запроса
return ShowResult($where); // Эта функция, единая для всех трёх случаев, выведет нам результаты поиска. Функция описана ниже.
} //function FindPhonesByName($q)
function FindPhonesByNumber($q){ // С цифрами оно всегда проще. Даже если есть зюрочки :-)
$where="phone LIKE '".str_replace("?", "%", $q)."' ORDER BY phone"; // Формируем Where- и order- части MySQL-запроса
return ShowResult($where); // Эта функция, единая для всех трёх случаев, выведет нам результаты поиска. Функция описана ниже.
} //function FindPhonesByNumber($q)
function FindPhonesByAddress($q){ // Вот тут придёццо паибаццо маленько. Например, потому, что номера домов бывают через дробь.
$q=" ".preg_replace("/[^А-ЯЁ0-9-/]/Usi", " ", $q)." "; // Убираем нафиг всё кроме букв, цифр, тире и знака "/"
$q=str_replace(" УЛ ", " ", $q);
$q=str_replace(" ПЕР ", " ", $q);
$q=str_replace(" ПР-Т ", " ", $q);
$q=str_replace(" ПР ", " ", $q);
$q=str_replace(" ПЛ ", " ", $q);
$q=str_replace(" Ш ", " ", $q);
$q=str_replace(" ДОМ ", " ", $q);
$q=str_replace(" Д ", " ", $q);
$q=str_replace(" КВ ", " ", $q);
$q=str_replace(" К ", " ", $q);
$q=preg_replace("/s([0-9]+)/[0-9]*/si", " \1/%", $q); // Учитываем дробь в номере дома
/* $q=preg_replace("/([А-ЯЁ]+)s/Usi", "\1% ", $q); */ // Позволяем вводить часть названия улицы
while( strpos($q, " ") !== false ) $q=str_replace(" ", " ", $q); // Убираем двойные пробелы
$q=trim($q); // и обрезаем пробелы с начала и с конца
// А теперь - бонус для тех идиоток, которым нужно найти Серёжу из 32-го дома:
// Пользуемся тем, что в Обнинске только одно название улицы состоит из двух слов: "Красных зорь". Иначе пришлось бы обрабатывать Array.
if( preg_match("/([А-ЯЁs]+s)КРАСНЫХsЗОРЬ/si", $q, $matches)
|| preg_match("/([А-ЯЁs]+s)[А-ЯЁ]+s[0-9]+/si", $q, $matches)
){ // Я очень надеюсь, что PHP в выражении (А || B) при А===true будет обрабатывать только А
$name=$matches[1];
$q=str_replace($name, "", $q);
$name="%".trim(str_replace(" ", "% ", $name));
$where="name LIKE '".$name."' AND address LIKE '".$q."%' ORDER BY BINARY(address)"; // Формируем Where- и order- части MySQL-запроса
return ShowResult($where);
} //if
$where="address LIKE '".$q."%' ORDER BY BINARY(address)"; // Формируем Where- и order- части MySQL-запроса
return ShowResult($where);
} //function FindPhonesByAddress($q)
function ShowResult($where){
if( preg_match("/\'s*\%[s\%]*\'/Usi", $where) ) return NOT_FOUND; //Паранойя на пустые запросы
//$where=iconv("windows-1251", "UTF-8", $where); // Раскомментить, если база в юникоде, а страница будет в windows-1251
$cnt=db_count("phonebook", $where); // db_count($table, $where) - это моя функция, подсчитывающая в $table число записей, соответствующих $where
echo "Найдено записей: ".$cnt."<br /><br />"; //Оператор echo - синоним функции print, выводящей что-либо в STDOUT. То есть, в браузер посетителю.
$limit=" LIMIT 0, ".N_AT_PAGE; // Дефолтовое окончание MySQL-запроса, лимитирующее выводимые записи
$PageList=""; // Дефолтовый список страниц пуст
if($cnt>N_AT_PAGE){
$nPages=(int)($cnt/N_AT_PAGE);
if($cnt>$nPages*N_AT_PAGE) $nPages++; // Число найденных записей почти наверняка не будет кратно N_AT_PAGE
$q=urlencode(param("q")); // для генерации ссылок
$CurrentPage=(int)param("page");
$pageStart=$CurrentPage-10; if($pageStart<0) $pageStart=0;
$pageEnd=$CurrentPage+10; if($pageEnd>$nPages) $pageEnd=$nPages;
for($i=$pageStart; $i<$pageEnd; $i++){
if($i==$CurrentPage) $PageList=$PageList." <b>".($i+1)."</b> ";
else $PageList=$PageList." <a href="phone.php?q=".$q."&page=".$i."">".($i+1)."</a> ";
} //for
$limit=" LIMIT ".$CurrentPage*N_AT_PAGE.", ".N_AT_PAGE;
} //if
$query="SELECT * FROM phonebook WHERE ".$where.$limit;
//debug($query); // debug - это моя отладочная функция
if($PageList) echo "Страница: ".$PageList;
?>
<table width="100%" border="1">
<tr bgcolor="#000000" style="color:#FFFFFF; font-weight:bold">
<td valign="top" width="40%">Фамилия, имя, отчество</td>
<td valign="top" width="12%">Дата рождения</td>
<td valign="top" width="15%">Место рождения</td>
<td valign="top" width="25%">Регистрация по адресу</td>
<td valign="top" width="7%">Телефон</td>
</tr>
<?
$res=mysql_query($query);
if(!$res) {ErrorReport(mysql_error()); return NOT_FOUND;} // ErrorReport - моя функция, присылающая сообщение об ошибке мне на мэйл
$n=0;
while($row=mysql_fetch_row($res)) {
echo "<tr".( ( (int)($n/2) )*2 == $n++ ? " bgcolor="#CCCCCC"" : "" ).">";
for($i=1; $i<count($row); $i++) echo "<td>".$row[$i]."</td>";
echo "</tr>";
}
?>
</table>
<?
if($PageList) echo "Страница: ".$PageList;
} //function ShowResult($q)
?>