[навигация по сайту с помощью php]материал подготовил: Дмитрий Турецкий 29.04.2004
Динамический сайт от статичного отличается тем, что выводом содержимого в нем занимаются различные скрипты, причем один и тот же скрипт выдает разные данные в зависимости от переданных ему параметров. И в сегодняшней заметке мы попробуем разобраться, как эти параметры передать и обработать, а заодно и с тем, как сделать адреса более читабельными…
Самым простым вариантом сайта является набор статических HTML-страниц. Адресация при этом жестко привязывается к имени файлов и от вас почти не зависит. «Почти» заключается в том, что для «более красивого» вида адресов вы можете создать некий управляющий скрипт или же использовать преобразование адресов с помощью mod_rewrite. Оба эти способа будут рассмотрены ниже.
Значительно более интересным и гибким является вывод данных с помощью скриптов. Указать скрипту, что именно он должен вывести, можно с помощью параметров, передаваемых методами GET или POST. Можно, теоретически, передавать параметры и с помощью cookie, но занятие это не совсем тривиальное, ненадежное (пользователь может «куки» запретить) и непонятно зачем нужное, так что его мы рассматривать не будем.
Разница между методами GET и POST заключается только в том, что GET-параметры видны в адресе запрашиваемого документа, а POST передаются в виде служебных заголовков. Кроме того, документы, вызываемые через передачу POST-параметров, как правило, не кешируются на прокси-серверах и не индексируются поисковиками, так что к такой навигации надо относиться с осторожностью. В частности, если ваши страницы генерируются динамически, то довольно удобно бывает комбинировать навигацию: с помощью GET-параметров определяется основное содержимое страницы, а с помощью POST выполняется, например, сортировка выводимых данных или выборка какой-то их части. Разумеется, вы не сможете одновременно передать и GET и POST-параметры — имеется в виду, что для основной навигации по сайту используется GET (при этом параметры «тонокой настройки» не передаются и используются значения по умолчанию), а для сортировок и выборок внутри выбранного основного раздела используется форма, которая передает необходимые параметры с помощью метода POST.
В PHP-скриптах использовать параметры очень легко — они находятся в символьных массивах $_GET или $_POST, а если вы не знаете, какой метод использовался (например, в случае с комбинированной навигацией), то можно использовать массив $_REQUEST. Таким образом, если вы запрашиваете документ по адресу http://www.mysite.ru/script.php?news=2, то в срипте script.php вы можете использовать переменную $_REQUEST[‘news’], которая в данном примере будет иметь значение 2.
Как правило, использование GET-параметров является первым этапом «динамизации» сайта. Например, если у вас на сайте есть несколько разделов, то может оказаться удобным написать скрипт, который будет выводить логотип, навигацию и прочие служебные вещи автоматически, а содержание выбирать, исходя из переданных параметров. Простейший вариант такого скрипта может выглядеть следующим образом:
<html> <head><title>Крутая динамическая страница</title></head> <body> Здесь будет логотип <?php $file = (isset($_REQUEST[‘section’])) ? $_REQUEST[‘section’].’.html’ : ‘default.html’; if (!file_exists($file)) $file = ‘default.html’; readfile($file); ?> А это стандартная подпись </body></html>
В этой странице логотип и подпись прописаны жестко, а выводом содержимого занимается PHP. Прежде всего, проверяется, был ли передан параметр section, и если да, значение переменной $file устанавливается равным переданному значению с дописанным расширением html, а если нет, то default.html. Следующая строчка проверяет, существует ли такой файл, и если нет, то, опять же, значение устанавливается в default.html. Последняя строчка читает и выводит указанный файл.
PHP значительно упрощает и облегчает работу с параметрами
Разумеется, подобный «динамичес
кий вывод статичных файлов» бывает нужен достаточно редко, хотя порой может оказаться удобен. Значительно чаще параметры нужны для динамического формирования страниц, скажем, на основе выборок из базы данных. При этом из адреса типа http://www.mysite.ru/section.php?id=2&sort=date внутри скрипта может формироваться SQL-запрос:
SELECT * FROM items WHERE section=$_REQUEST[id] ORDER BY $_REQUEST[sort]
(Настоятельно рекомендуется НИКОГДА так не делать и НИКОГДА не использовать передаваемые данные напрямую — ВСЕГДА перед использованием проверяйте тип и диапазон переданных данных!)
Через некоторое время после введения подобной системы появляется желание «облагородить» адреса, по возможности избавившись от знаков вопроса. Например, для сайта со статьями вместо адресов типа http://www.mysite.ru/article.php?id=13 хочется видеть что-то вроде http://www.mysite.ru/articles/13/ — такой адрес и выглядит немножко получше, и поисковиками индексируется чаще (некоторые поисковые серверы не индексируют страницы, если в адресе присутствует знак вопроса), и позволяет скрыть адрес и тип используемого скрипта. Это очень легко делается с помощью mod_rewrite:
При работе с параметрами всегда помните, что они ненадежны — пользователь может их исказить, как ему заблагорассудится!
Некоторым недостатком подобной схемы является то, что заходить на вашу страницу можно и по старому и по новому адресу — поисковики считают, что это две разные страницы и, соответственно, «размазывают» рейтинг между ними. Поэтому возникает желание принудительно перевести всех посетителей на использование новых адресов, для чего в mod_rewrite надо перед этим правилом вписать что-то вроде:
Здесь мы сначала проверяем, что был запрошен скрипт article.php с параметром (проверки RewriteCond), а затем преобразуем адрес к новому виду и с помощью внешнего редиректа с кодом ошибки 301 (страница постоянно перемещена) переадресуем посетителя. Обратите внимание, что при использовании RewriteCond для подстановки значения из скобок используется символ процента, а не доллара. Также обратите внимание на знак вопроса в конце адреса в директиве RewriteRule: если его не указать, то к новому адресу допишется переданная строка запроса, в результате чего адрес превратится в http://www.mysite.ru/articles/13/?id=13.
«Обратное преобразование» адресов используется редко, но может оказать некоторую помощь сайту
Теоретически, на этом можно и остановиться, но можно пойти еще дальше — использовать в адресе название статьи, например, — тогда посетитель, просто взглянув на адрес, сразу поймет, о чем там речь. Правда, для статей это вряд ли окажется очень полезно, но вот подобная адресация разделов бывает вполне оправдана и востребована, особенно на больших сайтах с развитой структурой — скажем, на архивах программ или документации. Согласитесь, что адрес http://www.listsoft.ru/internet/servers/http/ выглядит намного лучше, чем http://www.listsoft.ru/listing.php?cat=243.
Если разделов на сайте сравнительно немного и меняются они редко, то для подобной адресации можно использовать «стандартный» mod_rewrite, просто руками прописав достаточное количество директив RewriteRule. Если же разделов много или они периодически меняются, то значительно удобнее использовать «карту переадресации» или, как ее еще называют, отображение. Для начала надо создать файл с парами «ключ-значение», разделенными пробелами. Например, файл navigation.txt, который выглядит как
section1 1 section2 2 …
Затем надо объяснить серверу, что это именно отображение. Делается это с помощью директивы RewriteMap:
RewriteMap nav txt:/www/navigation.txt
Здесь первым параметром указано имя отображения, которое затем будет использоваться, а вторым — тип преобразования и адрес используемого файла. О возможных типах преобразования стоит почитать в документации сервера — это может быть не только текстовый файл, как в данном случае, но и встроенные функции Apache и написанная вами программа.
Ну, а когда карта отображений задана, надо сказать серверу, что он должен преобразовывать адреса в соответствии с этой картой:
RewriteCon
d ${nav:%{REQUEST_URI}} ^([0-9]+)$ RewriteRule ^.*$ /navigation.php?id=%1 [L]
Первая директива просматривает нашу карту отображений и сравнивает с запрошенным адресом: если соответствие найдено, то она сохраняет в переменной %1 значение кода из этой карты. После чего директива RewriteRule переписывает наш запрос, передавая скрипту navigation.php параметр id, равный найденному предыдущей директивой значению. Таким образом, адрес http://www.mysite.ru/section1 будет преобразован в http://www.mysite.ru/navigation.php?id=1.
Правда, в реальной жизни этот пример стоит немножко усложнить — ведь адрес могут набрать в верхнем или нижнем регистре, поставить в конце адреса косую черту или не поставить, передать какие-то дополнительные параметры или не передать… Так что правильнее будет написать что-то вроде следующего: