На главную страницу
Форум txt.version   




Статья :: Имитация файлов и директорий. Часть 2

Имитация файлов и директорий. Часть 2

detail
20.1.2001

В прошлом выпуске я описал работу с ЧПУ ("человекопонятные УРЛы") через ошибку #404. Сам пользуюсь именно этой схемой. Но через день после публикации материала свой отзыв написал Константин Шевченко (aka cat) и предложил мне рассказать публике о других способах работы с адресами на сайте. Он же меня и консультировал.

В отзывы, так же написали, что это серьезно грузит систему. Да, грузит. И я об этом честно написал. И еще одна поправка: диалог в отзывах

Посетитель: А интересно, что скажут поисковики на етот мнимый ErrorDocument?
Я: Поисковики считают такие адреса нормальными - они делят всё на 200 Ok и 404 Not Found. А остальное им по барабану.


Поисковики, конечно же, не делят все на 200 и 404. Они знают и другие коды сервера, просто никто не может проверить на уровне программ, существует ли документ, который прислал сервер или нет. Если код 200, значит существует и доступен. И ничего более.

Потом Юра Буров написал по поводу предыдуего материала в "Еженедельках". Однако, это не все, что можно написать, как думает он.

Одна вещь, которую забыл описать в предыдущем выпуске - виртуальный файловый архив. Через ErrorDocument вполне возможно отслеживать запросы к несуществующей директории download и выдавать запрошенные файлы из базы, а администратор сайта мог бы работать с этим архивом через веб-форму. Чтобы правильно выдавать тип файла (content-type), нужно брать его тогда, когда его закачивает администратор. В таблице файлов сделать дополнительное поле, в котором хранить эти типы, и выдавать их в заголовке. Разумеется, произойдет снижение производительности сервера.

А теперь о том, что описал Костя. Перечислю способы по возрастанию сложности (порядок, впрочем, спорный).

Сервер ищет файл с тем же именем

Оказывается, достаточно прописать в установках директории (httpd.conf или .htaccess) строку

Options Multiviews

или, если директива Options уже есть, добавить MultiViews к ней. Тогда если пользователь набирает "<адрес директории>/foo/bar", сервер будет искать файл с именем "foo" и с любым расширением. Найденный с наибольшим совпадением (вот это для меня загадка) файл он обработает с его типом mime, то есть если есть news.php, а набран адрес news/, то сервер отдаст адрес на обработку php. Если это картинка, то сервер отдаст ее броузеру именно как картинку (послав соотвествующий заголовок content-type). А в news.php разбираем $REQUEST_URI. Например, если новости выводятся целой лентой, либо за определенную дату, разбор можно сделать таким:

/* Первый вариант - когда набран адрес типа "/news/010120", возможно с дробью на конце. Символы ^ и $ здесь обозначают привязку к началу и концу строки. Подстрока [0-9]{6} означает 6 цифр (если у вас новости могут быть датированы 1999-м годом и раньше, используйте адреса с полным форматом года и 8 цифр вместо 6). */
if (ereg("^/news/([0-9]{6})$", $REQUEST_URI, $match) || ereg("^/news/([0-9]{6})/$", $REQUEST_URI, $match)) {

  }

/* второй вариант - набран адрес просто "/news" или "/news/" */
elseif (ereg("^/news/$", $REQUEST_URI) || ereg("^/news$", $REQUEST_URI)) {

  }

/* запросы ко всем остальным адресам (в этом файле) считаются попытками взлома сайта =) */
else
  die ("Error 404 Not found");

То же самое можно сделать, например, с каталогом продукции фирмы - вынести все это дело в отдельный файл catalogue.php, а адреса сделать вида "/catalogue/rubrik1/rubrik2/rubrik3". При этом в файле catalogue.php начало строки будет откусываться, а дальше можно обработать по принципу, описанному в предыдущем выпуске. Остальное же можно отправить, опять же, в ErrorDocument.

Сервер разбирает запрос

Метод похожий, но на вскидку менее ресурсоемкий, потому что не приходится искать файлы по директории.

В установках директории (опять же httpd.conf или .htaccess) пишем:

<FilesMatch "^(news)$">
ForceType application/x-httpd-php
</FilesMatch>

В директории лежит файл с именем "news" (именно "news", без расширения). Когда запрашивается адрес "/news", либо "/news/bla-bla-bla", сервер выполняет файл news как php-скрипт. А внутри него производится обработка переменной $REQUEST_URI.

Чтобы не писать для каждого подобного файла свой блок FilesMatch, нужно немного изменить строку шаблона. Пусть сервер ищет файлы без расширения, то есть те, у которых в имени нет точки:

<FilesMatch "^([^\.]+)$">

Очень удобно! Когда-нибудь поставлю такое же и себе.

Сервер переписывает запросы

Очень полезная вещь mod_rewrite. Ею можно сделать все вышеописанное, и много другого.

К сожалению, моя битва с mod_rewrite не увенчалась успехом (Костя пишет, что нижеописанного достаточно для работы Rewrite Engine под Unix. У меня под win98 - ни в какую...). Поэтому описываю очевидные вещи и то, что описал Костя.

Для начала надо раскомментировать строку

LoadModule mod_rewrite <путь к модулю/имя файла>

в httpd.conf. В конфигурации директории пишем строку "RewriteEngine On". Затем - команду RewriteRule:

RewriteRule <шаблон> <замена>

Например RewriteRule ^(.*).html$ /otherdir/$1.html (все без кавычек). Вот, собственно, и все. Все, что я так и не смог проверить : Я спросил у ясеня, я спросил у тополя, я спросил у форума... форум не ответил мне. (мелодично) Я спрошу у публики... На всякий случай, спрашиваю у уважаемой публики: как запустить Rewrite Engine под win98 se + apache/1.3.14 + php/4.0.4-Antonio (установлен как модуль) ?

А пока еще один пример (опять же от Шевченко):

RewriteEngine On
RewriteRule ^(.*).htm$ /portal/$1

<FilesMatch "(portal)$">
ForceType application/x-httpd-php
</FilesMatch>

Там лежит один файл с именем "portal", в который перенаправляются все запросы к html-файлам в данной директории. И получается, как будто там лежат файлы.

Напоследок вспомним Ленту.ру.

Вот здесь, в са-а-амом конце Носик говорит про ресурсоемкость их технологии. "Издательская машинка, написанная Максимом Евгеньевичем Мошковым, (который библиотека) интересна тем, что она весит около 60Kb"

Не знаю, что из себя представляет эта система (скорее всего, скомнилированный ), гадать не буду. Мне хотелось бы прикинуть, как динамическую адресацию можно реаизовать через php. Впрочем, тут не в нем дело - был бы Апач. Итак, схема адресов <рубрика>/<год>/<месяц>/<день>/<новость>. Если отрезать имя новости, получим материалы рубрики за день. Если отрезать день, месяц и год, получим последние материалы рубрики.

RewriteRule ^([a-z]+)/$ rubika_last/$1
RewriteRule ^([a-z]+)/([0-9]{4})/([0-9]{2})/([0-9]{2})/$ rubrika_date/$1/$2-$3-$4
RewriteRule ^([a-z]+)/([0-9]{4})/([0-9]{2})/([0-9]{2})/([a-z]+)/$ rubrika_news/$1/$2-$3-$4/$5

<FilesMatch "^rubrika">
ForceType application/x-httpd-php
</FilesMatch>

Преимущества этого метода по сравнению с единой точкой входа EerrorDocument очевидны: движок php интерпретирует только то, что будет выполняться. Никаких switch/case или if/elseif/else, никаких лишних строк.

Все остальное - отдаем ErrorDocument "как в предыдущей задаче".

Имитация файлов и директорий. Часть 2

страницы в данном разделе 
 get yahoo proxy  Имитация каталогов
 Имитация файлов и директорий. Часть 2  Building Dynamic Requests
 Виртуальный магазин?  Параллельное выполнение скриптов
 Это программа отсылает сообщение на Асю.  Передача из скрипта методом POST
 Пример работы с сессиями.  СЕССИИ - обучение и /правильное/ использование
 Как вытащить слова из текста?  Защита от двойного сабмита
 Как вырезать со страницы все ссылки?   


Разделы
Околокомпьютерная литература (375)
Программирование (102)
Программы (75)
ОС и Сети (49)
Интернет (29)
Аппаратное обеспечение (16)
Базы данных (6)

Содержание сайта (выборка)
Apache
Протоколы TCP/IP (принципы, протоколы и архитектура)

PHP, PELR, JSP
PHP
JavaServer Pages (JSP)

Базы данных
Основы mysql
СУБД INFORMIX
СУБД POSTGRES
Основы проектирования реляционных баз данных

HTML, javascript
Спецификация HTML 4.01
Каскадные Таблицы Стилей, Уровень 2
Клиентский JavaScript. Справочник.
JavaScript руководство пользователя
Серверный JavaScript 1.4. Руководство по Использованию.

Паскаль, C, C++, C#
GCC (примеры)
FAQ Валентинa Озеровa DELPHI
C





 
©  programming-lang.com  справочник программиста