Октябрь 3, 2002

Достойная замена ModRewrite для работы с понятными адресами

В статье рассказывается о простом способе разбора URL-ов с помощью PHP. Будет полезна тем, кто по разным причинам не может установить или настроить mod_rewrite.

Если на вашем хостинге отсутствует ModRewrire, все прелести которого уже были описаны в журнале nbsp.ru, но вы работаете с каким-нибудь серверным языком вроде PHP, вы можете без проблем воспользоваться другим, на мой взгляд, даже более изящным и "переносимым" способом.

Итак, весь ваш сайт обслуживает один скрипт, который в нормальном состоянии вызывается как /index.php. В зависимости от выбранного каталога ("виртуального" в нашем случае) этот скрипт должен показать ту или иную запись из базы, выполнить ту или иную операцию.

В случае с ModRewrite передача параметров скрипту осуществляется при помощи серии хитрых правил. Мы же воспользуемся именно тем фактом, что запрашиваемые каталоги реально не существуют.

Сделаем наш скрипт обработчиком 404-й ошибки ("документ не найден") и посмотрим, что получится! Пишем в .htaccess корневого каталога сайта:

Теперь, какой бы адрес ни ввел пользователь сайта, запрос непременно адресуется данному скрипту.

А вся хитрость заключается в том, что скрипт может узнать, какой запрос сделал пользователь. Это осуществляется посредством анализа переменной окружения (environment) REQUEST_URI. Например, в PHP значение этой переменной можно получить так:

Обратим внимание на то, что эта переменная будет содержать абсолютно полный пользовательский запрос, включая каталог, файл в каталоге и параметры (то, что следует за вопросительным знаком). Если нас интересует только каталог, отсечем все ненужное:

Сначала мы отсекаем параметры запроса (который, кстати, можно получить из переменной окружения QUERY_STRING), затем все, что находится после последнего слэша (оставляя тем самым только путь к каталогу). А какие действия выполнять для того или иного каталога - решать только вам, дальнейший "разбор" сделать очень несложно.

Не забудьте только предусмотреть внятное сообщение о некорректном пользовательском запросе, если введенный им адрес не соответствует никакому из запланированных действий скрипта (нечто вроде "внутренней, виртуальной ошибки 404").

Этот же прием, кстати, можно применять и для отображения однородной информации из реально существующих каталогов. В этом случае нам потребуется описать скрипт как "индексный" файл для всех каталогов:

После этого запрос к любому каталогу, содержащему какую-то информацию, все равно будет попадать в скрипт, который, проанализировав REQUEST_URI, решит, что конкретно и откуда показывать.

Автор:

Комментарии

1. 27.09.04 09:35 От: ion

Красивое решение! Но есть одно "но", надо "знать" существует ли файл или документ в базе, чтоб в случае чего послать пользователя на реальную 404.

2. 28.09.04 12:29 От: FiW

самая большая проблема в другом -растущих error.log'а (если сервак не правильно настроен) и потери инфы в post'ах... последнее самое болещненное

3. 29.09.04 18:06 От: mxdmg

И ещё один минус обработки через 404ю ошибку это невозможность передачи скрипту переменных GET&POST

4. 07.10.04 10:12 От: eo

Есть гораздо более простой способ:
1) включаем в апаче Options Multiviews, чтобы к файлу например /news.phtml можно было обращаться как к директории, т.е. /news/
2) К файлу /news.phtml обращаемся например так: /news/15/09/2004/
3) В результате обработки PATH_INFO, содержащей "/15/09/2004/" мы имеем в данном примере три готовых к употреблению переменных.

Этот способ проще и лучше способов с мод_рерайтом и 404. Я использовал его для сайта с 50мб БД, соответственно огромным количеством записей в этой БД, и нехилым количеством посетителей.

5. 09.10.04 19:25 От: анонимНО

а разве некоторые прокси не подсовывают свои странички 404 ?

6. 23.10.04 20:44 От: mxdmg

2анонимНО : для этого нужно послать заголовок что страница существует
вот он
if(stristr($HTTP_SERVER_VARS['SERVER_SOFTWARE'], 'php')){
header("HTTP/1.1 200 Ok");
}else{
header("Status: 200 Ok");
}

7. 31.08.05 10:01 От: akxxiv

А так же поисковики не индексируют страницы с 404 щшибкой.
Возможно решение от mxdmg справляется с этим, но не знаю...
Я перешел на модрерайт

8. 26.06.06 17:23 От: 1name.ru

ModRewrite рулит!
Все остальное - извращение.

Ваш комментарий

Обсудить на форуме?

Подумайте, прежде чем высказать своё мнение. Постарайтесь сделать свой комментарий полезным для других. Не используйте ненормативную лексику. Пользователи, пишущие "от нечего делать" бессмысленные наборы символов, будут блокироваться навсегда.