Чпу php

Если Вы умеете немного кодить и пишите свои скрипты, я вам расскажу как легко сделать ЧПУ (человеко понятный урл) с помощью .htaccess.

Что такое ЧПУ?

Например, у нас есть ссылка на страницу новостей с ID номером новости:

http://site.ru/news.php?id=4

Чтобы сделать такой URL красивее и удобнее, придумали ЧПУ, т.е. представление адреса, например в таком виде:

http://site.ru/news/4/

Скажете не очень наглядно? А вот такой пример:

http://site.ru/index.php?do=article&name=kak-sdelat-chpu

а с ЧПУ:

http://site.ru/articles/kak-sdelat-chpu/

Сделать это очень просто. Для веб-серверов Apache, есть встроенный модуль mod_rewrite. На большинстве хостингов он есть, так же как и на денвере.

Создаем файл .htaccess и кладем его в корень сайта. Первой строкой в этом файле мы пишем:

RewriteEngine on


Эта строка включает модуль mod_rewrite. Далее, мы пишем сами условия куда и зачем обращаться. Для нашего первого примера, код будет выглядеть так:

RewriteEngine on
RewriteRule ^news/([0-9]+)/? news.php?id=$1 [L]

Он будет перенаправлять с http://site.ru/news/4/ сюда http://site.ru/news.php?id=4
Все эти условия обычно указываются в htaccess с помощью регулярных выражений.

По второму примеру, код будет выглядеть так:

RewriteEngine on
RewriteRule ^articles/([-a-zA-Z0-9_]+)/? index.php?do=article&name=$1 [L]

Т.е. с адреса http://site.ru/articles/kak-sdelat-chpu/ нас перебросит на http://site.ru/index.php?do=article&name=kak-sdelat-chpu. Точнее пользователь не увидит реального адреса, а увидит только наш ЧПУ.

Как видите, все достаточно просто — создаем файл htaccess, пишем две строчки и готово! :)

По регулярным выражениям меня не спрашивайте, я не шарю :) Знаю только:

[0-9]+ — это только для цифр

[-a-zA-Z0-9_]+ — это для латинских больших, маленьких, дефиса и подчеркивания


Если во соображаете в регулярных выражениях, Вам будет очень легко написать любое правило. А кто не соображает, тут нужно смотреть примеры, которые я привел и пробовать. Я вчера попробовал, получилось! Не сразу конечно, перерыл кучу инфы, но разобрался.

Надеюсь понятно описал. Будут вопросы, спрашивайте.

UPD by Hugo: Если использовать конструкцию [QSA,L], тогда ЧПУ сможет принимать GET запросы. Т.е. если мы будем без [QSA,L] передавать GET-параметр (http://site.ru/articles/kak-sdelat-chpu/?Get_param=1) то выкинет 404 ошибку. Чтобы этого не происходило и мы смогли принимать GET запросы, нужно:

Вместо этого:

RewriteRule ^news/([0-9]+)/? news.php?id=$1 [L]

Нужно написать [QSA,L] на конце:

RewriteRule ^news/([0-9]+)/? news.php?id=$1 [QSA,L]

crazy-russian.ru

 

На файл htaccess мы сильно отвлекаться не будем, его работа не так уж и сложна, тем более если Вы знакомы с регулярными выражениями в php. Вот, что касается самого модуля ЧПУ, то он представлен в виде двух файлов ( ну можно и в один, но у меня почему то получилось два =) ) и «сети условий» по всему движку. Не пугайтесь, под термином «сети условий», я подразумеваю тот геморрой с автоматической смены ссылок по всему движку! Сегодня мы займемся лишь фундаментом, и добьемся того что бы пост, на странице нашего блога, был доступен по адресу с человеко-понятной ссылкой


Цели я указал в анонсе, так что сейчас пару слов для новоприбывших, и приступим =)

 

Для тех кто на блоге в первые

 

Если Вы на блоге в первый раз, то эта маленькая заметка именно для Вас! Пускай тема ЧПУ обширная и применима к любому проекту, Вам, именно в материале на этой странице, будет очень сложно выявить что-то полезное для себя, по причине того, что этот пост, как и большинство на моем блоге, является частью цикла статей «Создать блог с нуля». Цикл ориентирован на аудиторию которая хочет на практике научится программировать на php. Если Вы из таких, то добро пожаловать! Переходите по ссылке, что я дал Вам выше и приступайте к изучению изложенного мной материала

Если Вы собираетесь задержаться на моем блоге, то подпишитесь на RSS ленту блога через ридер, или же по почте

 

Новая колонка в таблице базы данных

 

Так как у нас пока нет модуля который автоматически, из заголовков, делал бы нам имена ссылок, то придется не только создать колонку но и заполнить ее каким-нить именем. Только учтите, что имя должно состоять из маленьких букв английского алфавита, плюс к этому не должно быть пробелов, вместо них ставим тире ( — ). Это условие обязательно, ибо скрипт проверки будет отсеивать не правильные адреса, перекидывая пользователя на главную страницу блога.

Заходим в структуры таблицы blog, и после id создаем новую колонку

 


создаем новую колонку в таблице базы данных

 

Заполняем поля приблизительно вот так ( имя поля nameurl )

 

заполняем поля, создавая новую колонку в таблице базы данных

 

Теперь, необходимо заполнить новую колонку. У меня лишь одна запись в базе данных, поэтому для меня заполнение новой колонки не является проблемой =)

 

заполняю новую колонку в таблице базы данных

 

В конце имени необходим поставить «.html». Если у Вас в планах не использовать такое окончание у Ваших страниц, то можете не писать, только в этом случае Вам придется немного переделать файл htaccess, а именно убрать расширение там.


Я для тестовой странице использовал вот такое имя: dobro-pozhalovat.html

Ну чтож, с этой задачей мы справились, теперь приступим к самому файл htaccess

 

Создаем файл htaccess

 

Создавать лучше всего с помощью программы Notepad++, ибо в некоторых случаях виндоус ругается, что у файла нет имени, ведь имени и в правду нет =) только расширение .htaccess

На всякий случай я скину Вам файл, вот он. Этот файл необходимо поместить в корень нашего блога

 

правильное размещение файла htaccess

 

Содержимое файла следующее:

Первая строчка включает возможность перенаправления с динамических ссылок на ЧПУ. Вторая отвечает за ссылки на посты. То есть если ссылка будет вот такого вида

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

Третья строчка отвечает за ссылки к категориям

Ну и последняя строчка отвечает за ссылку ведущая на форму обратной связи

Обратите внимание что регулярное выражение находится в скобках, если Вы знакомы с регулярками, то прекрасно знаете, что скобки это сохранение. Вопрос, куда переносятся сохраненные данные? Ответ: В переменную 1. Да, именно 1 (единица).


Если Вам нужны ЧПУ без .html то редактируйте регулярное выражение в файле htaccess, на такой вид ссылок, который Вам нужен!

Особо останавливаться тут не будем, я многое тут не знаю, поэтому долго разглагольствовать на эту тему не имею право, единственное что бы я еще добавил, это пару слов о флаге [L]. Я может и ошибаюсь, но как я понял этот флаг останавливает проверки, что идут ниже, это что-то типа break (прерывание работы всего цикла) у циклов.

Под итожу то что написано в файле htaccess: Условия, для каждого вида станиц которые есть у нашего движка, а именно

  • для постов
  • для категорий
  • для страницы контактов

Если Вы знакомы с регулярками, то разобраться в файле Вам не составит труда.

 

php функция chpu() — Алгоритм поиска id записи в таблице базы данных

 

Начнем с создания алгоритма поиска. Для этого нам понадобится знать в какой таблице искать и что искать. У Вас может возникнуть вопрос, что значит в какой таблице? Ведь таблица у нас одна — blog. Это не совсем так, сегодня мы рассматриваем только посты, но так же нам известно, что у категорий тоже есть свои ссылки, а таблица которая будет содержать имена категорий называется menu, именно поэтому алгоритм должен знать в какой таблице ему искать. Пускай функция chpu() на данном этапе будет работать лишь на половину, зато в следующих постах нам не придется редактировать ее (функцию).


Создаем файл chpu.php помещаем его в пользовательские модули нашего движка, и пишем в этом файле следующую функцию:

Функция очень простая, так что не будет на ней останавливаться, тем более я уже не раз разъяснял логику поиска id в таблице.

 

Скрипт позволяющий определить какая страница открыта

 

Цель этого скрипта определить в каком режиме запустить функцию chpu(). Определить это можно по GET запросу который создает нам сервер при обращение к станице по ЧПУ. Если Вы внимательно смотрели содержимое файла htaccess, и приблизительно поняли его работу, то Вы должны догадаться, что сервер для себя определяет ссылку вот такого вида

То есть, если пользователь обратился к станице с помощью ЧПУ то сервер создаст GET запрос post, создание такого запроса сигнализирует нам о том что пользователь обратился на страницу поста, стало быть функцию chpu() необходимо запускать в режиме поиска id в таблице blog

Создаем файл getchpu.php, сохраняем его в папке пользовательских модулей и пишем в нем следующий скрипт

Логика скрипта следующая:

  • Скрипт будет работать только в случае если блог работает в режиме вкл ЧПУ, то есть переменная chpu равна единице (это сделано для того чтобы режимы можно было поменять воздействуя лишь на одну переменную)
  • Далее подключается функция поиска id в базе данных

  • Дальше идут два варианта развития, и оба они работают по той же логике, то есть если существует GET запрос post или category то запускается проверка на корректность имени. Эта проверка поможет избежать простейших способов взлома нашего движка. Если проверка прошла успешно (если же нет, то нас перекинет на главную страницу) запускается функция chpu(), тем самым в переменную blog или cat (в зависимости от того какая часть скрипта будет работать =)) попадет id записи в базе данных. Если переменная пустая, то нас перекинет на главную страницу.

Если Вы создаете ссылки без .html, то Вам придется переделать регулярное выражение, ибо Ваши ссылки не пройдут проверки!

Тут есть один момент. Если Вы писали движок с самого начала курса, то у Вас скорее всего нет переменной server_root. Если Вы ставили копию движка, что я давал в посте «Установка нашей CMS», то эта переменная у Вас есть.

Если у Вас нет этой переменной, то откройте пользовательский файл index.php, и сразу после подключение к базе данных пропишите эту переменную

Значение переменной является адрес Вашего блога. Эта переменная необходима была в админке для авторизации, тут же она необходима для реализации ЧПУ, в частности для тега <base> что мы применим чуть ниже.

 

Подключаем модуль ЧПУ к нашему движку

 


Открываем пользовательский файл index.php, и сразу после подключения к базе данных пишем вот такой код

Первая строчка, как Вы поняли, ручное включение режима ЧПУ. Вторая строчка, подключение скрипта позволяющая определить открываемую страницу, в этом же скрипте подключается алгоритм поиска записей.

Теперь в самом низу, перед строчкой

Создаем переменную urlsite

Эта переменная необходима для того чтобы определить базовую ссылку сайта. В шаблоне index.html после строчки

вставляем вот такой тег

Этот тег позволяет определить корень сайта, тем самым мы избавимся от глюка который мешает правильно определить пути к стилям. Если не поместить этот тег в код шаблона, то все страницы находящиеся по ЧПУ перестанут грузить стили, ява скрипты, и если я не ошибаюсь то и картинки

 

rio-shaman.ru

Что такое ЧПУ?

Что такое ЧПУ

ЧПУ – это исковерканная англоязычная аббревиатура SEF URL (search engines friendly url). Она обозначает адреса ссылок, которые дружелюбны для поисковых систем. О ЧПУ я также писал в статье про внутреннюю оптимизацию сайта. В русскоязычном варианте SEF URL пишется как ЧПУ – человеко-понятные url. Что всё это значит? Это значит, что адреса ваших ссылок будут иметь осознанный текст, а не технический мусор, за примером можете сходить по ссылке выше.


Какие преимущества дают SEF URL?

Во-первых, очевидно, что ЧПУ ссылки уже в самом своём адресе могут содержать полезную для пользователя информацию. Из такого адреса сразу понятно, о чём будет статья или страница в целом.

Во-вторых, SEO. Такие ссылки приветствуются поисковыми системам, пару лет назад они могли бы дать вам значительный перевес над конкурентами. Сегодня подобные ссылки являются само собой разумеющимися, сейчас редко встретишь сайты с не ЧПУ ссылками, однако они до сих пор есть.

В-третьих, это престиж. Когда я захожу на сайты, где вместо понятного и красивого адреса в ссылках содержится разного рода мусор, а то и засекреченная информация – я задаюсь вопросом: «Вроде бы приличный сайт, но почему разработчики не сделали ЧПУ? Неужели это было так сложно? Может им настолько нет дела до подобных вещей или просто не хватает знаний и навыков?». В общем, для меня такие сайты большая загадка.

В-четвёртых, безопасность. Сайты с ЧПУ ссылками не содержат в своём адресе техническую информацию переданную методом GET (уроки PHP), которую можно запросто использовать для взлома сайта.

И последнее: ЧПУ – как средство навигации. Если ссылка понятна пользователю, то он сам может переходить по разделам сайта, просто редактируя ваш URL. Например:

http://site-on.net/useful/2-sublime-text-2

Если удалить из данной ссылки её последнюю часть (2-sublime-text-2), то мы попадём в раздел, к которому относится данная статья:

http://site-on.net/useful/

В данном случае это раздел «Инструменты». То есть благодаря SEF ссылкам мы можем построить понятную людям и роботам иерархию нашего сайта, что опять-таки будет полезно и для посетителей и для продвижения в поисковых системах.

Недостатки ЧПУ ссылок

Первое: возможно, вам придётся повозиться и даже помучаться, чтобы их настроить или вовсе сделать с нуля.

Второе: ваш сайт станет дольше грузится, а именно, на пару десятитысячных секунды 🙂 Это связано с тем, что для работы ЧПУ подключается специальный модуль веб-сервера Apache – mod_rewrite, которому понадобится это «огромное» количество времени на обработку ссылок.

Когда ЧПУ не нужны?

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

Также ЧПУ будет излишеством в back-end вашего сайта, то есть в панели администратора.

Что ещё нужно знать о ЧПУ?

Во всех актуальных версиях CMS данная проблема уже решена. Всё что вам нужно, чтобы сделать ЧПУ ссылки, это лишь включить соответствующие настройки в движке вашего сайта.

SEF URL

Но что если мы имеем дело с сайтом на чистом PHP, без CMS, или же хотим разработать свою собственную CMS в которой хотим сделать SEF URL? Для подобных случаев, а также для людей, которые хотят углубиться и понять всю суть преобразований обычной ссылки в ЧПУ, я и написал остальную часть статьи. Если вы читали мои предыдущие статьи, то знаете, что мой блог как раз относится к этой категории, то есть сайтам, написанным с нуля на PHP, без использования готовых CMS.

Ах да, ещё один момент: из личного опыта не советую делать кириллических URL.

Коротко: в чём вся суть?

Пишу для тех, кто совсем не в курсе дел. Везде в наших тегах гиперссылки мы будем указывать ЧПУ адреса:

<a href="http://site-on.net/useful/2-sublime-text-2">Sublime Text 2</a>

Суть в том, чтобы из красивого и понятного человеку URL (ЧПУ) сделать на лету URL, который будет полезен разработчику PHP (не ЧПУ):

<a href="http://site-on.net/index.php?category=useful&article=2-sublime-text-2">Sublime Text 2</a>

При этом всем на свете (посетителям, поисковым системам, всем) будет видна именно ЧПУ ссылка, но мы как разработчики PHP будем знать, что таит в себе URL на самом деле. В конце статьи, для полного понимания, я покажу все этапы, как ЧПУ работают у меня на блоге.

Создание SEF ссылок с помощью mod_rewrite

mod_rewrite – это модуль веб-сервера Apache, предназначенный для перезаписи URL. Естественно, для начала работы вы должны включить этот модуль в настройках Apache, эти настройки находятся в файле httpd.conf, вам нужно будет раскомментировать строку с именем данного модуля. У 99% хостинг-провайдеров он включён, за исключением совсем ужасных хостингов. Кстати говоря, используя Denwer, у меня не получилось нормально настроить собственные ЧПУ, мне не захотелось долго искать в чём именно проблема (мешают собственные редиректы Денвера) и я установил Апач отдельно. Для тех, кто не знает, как установить сервер Апач не используя Денвер, я напишу инструкцию в одной из будущих статей. А здесь мы продолжаем разбирать наши ЧПУ.

Все наши правила преобразований URL записываются в небезызвестный файл .htaccess, который должен лежать в корне нашего сайта.

Для корректной работы mod_rewrite в нём обязательно должна быть написана следующая строка:

Options +FollowSymLinks

Или, в частности, для моего хостинга:

Options +SymLinksIfOwnerMatch

Далее подключаем наш модуль rewrite к конкретной папке, то есть к папке, в которой лежит наш .htaccess:

RewriteEngine On

Имеем следующий файл .htaccess:

Options +SymLinksIfOwnerMatch RewriteEngine On 

Правила и условия mod_rewrite

Все правила записываются с помощью команды RewriteRule, после которой ставится пробел и записывается шаблон ваших ЧПУ с помощью регулярных выражений, далее ставится ещё один пробел и указывается строка, в которую мы хотим преобразовать данный шаблон, где $1,$2,…$n – наши переменные. Более подробно о регулярных выражениях вы можете узнать по приведённой выше ссылке, а также далее в данной статье. Давайте рассмотрим пример:

RewriteRule ^useful/([a-z]*) /index.php?category=useful&article=$1

Где ^useful/([a-z]*) – это шаблон ожидаемого url,

а /index.php?category=useful&article=$1 – это то, во что мы его конвертируем, если пришедший URL подошёл под шаблон.

При этом $1 равен тому, что написано в круглых скобках, то есть $1 = [a-z]* Если бы круглые скобки встречались 2 раза, то у нас были бы переменная $1 и $2, если круглые скобки встречаются 3 раза, то переменные $1, $2, $3 и так далее. При этом переменные создаются в том же порядке, как идут круглые скобочки.

Понятно? – молодцы. Непонятно? — идёмте дальше, мы ещё к этому вернёмся. Также хочу обратить ваше внимание на то, что для лучшего понимания статьи, вы уже должны обладать начальными знаниями о PHP, а также о работе с методами GET и POST. Продолжаем.

Для того чтобы наш обработчик, то есть mod_rewrite не срабатывал каждый раз без надобности, мы в RewriteRule указываем шаблон, которому должны соответствовать приходящие URL. Если URL не соответствует шаблону, то mod_rewrite просто не сработает и не преобразует пришедший SEF URL в URL, с которым мы можем работать.

То есть на данном этапе вам важно понять саму суть: в ЧПУ ссылках не передаются параметры, а без параметров мы не можем ничего сделать в PHP с этой ссылкой, поэтому с помощью mod_rewrite мы преобразуем ЧПУ ссылку без параметров в не ЧПУ ссылку с параметрами. Что такое параметры? В примере выше имеем 2 параметра:

/index.php?category=useful&article=$1

Параметр category и параметр article.

Опять-таки обращаю ваше внимание, что про параметры вы уже должны были знать, я лишь вкратце вам напомнил.

В шаблонах мы можем использовать символы и символьные классы. Символ точки обозначает абсолютно любой символ.

  • . – любой одиночный символ
  • [redf] – это класс символов. Обозначает наличие одного из перечисленных символов с учётом регистра.
  • [a-z] – класс символов. Обозначает наличие одного из символов в промежутки от a до z, то есть весь английский алфавит.
  • [a-zA-Z] – то же самое, только без учёта регистра, то есть весь алфавит, включая и большие и маленькие буквы.
  • Можно и с цифрами: [0-9]
  • Естественно, всё можно комбинировать: [a-zA-Z0-9]
  • [^rewfad] – класс символов, но со знаком ^ внутри квадратных скобочек обозначает, что шаблон НЕ должен содержать данных символов.
  • site|cite – обозначает альтернативу: подходит site или cite.

Квантификаторы или кванторы

Все предыдущие примеры обозначали один символ (одну единицу), а что если мы хотим показать, что символов из этого промежутка [a-zA-Z] может быть не один, а сколько угодно. Для этого мы должны использовать квантификаторы:

  • ? — 0 или 1 символ из предшествующего текста (класса символов, символа и тд.)
  • * — 0 или любое количество символов из предшествующего текста (n>0)
  • + — 1 или любое количество символов из предшествующего текста (n>1)
  • {n} — ровно n символов, где n – конкретное число.

Например:

  • {4} — должно быть ровно 4 символа из предшествующего текста.
  • {4,5} — 4 или 5 символов
  • {,6} — от нуля до 6 символов
  • {4,} — от 4 до бесконечности символов

Примером может послужить наша уже известная строчка:

RewriteRule ^useful/([a-z]*)

В которой мы применили квантификатор (квантор) звёздочку (*) после класса символов [a-z]. Это значит, что в нашем URL после useful/ могут находиться символы от a до z в любом количестве и, естественно, в любой последовательности, а могут и не быть вовсе. Домен в счёт не берём, он подразумевается сам по себе.

Экранирование

Также при составлении шаблона не стоит забывать и про экранирование. Если вы хотите заключить в класс символов, например, символ точки, то вам нужно её заэкранировать, так как без экранирования точка (служебный символ) обозначает абсолютно любой символ:

[a-zA-Z0-9.]

Тоже самое касается и квадратных скобочек, они у нас обозначают класс символов, поэтому если в вашем url могут быть квадратные скобочки их нужно заэкранировать:

[a-zA-Z0-9.[]]

Ограничение начала и конца строки (маркеры)

Для того чтобы указать начало или конец строки, без учёта домена, используются символы:

  • ^ — начало URL
  • $ — конец URL

То есть в нашем первом примере мы указали, что наш шаблон начинается именно с начала URL, а не откуда угодно (с середины, с конца):

RewriteRule ^useful/([a-z])

Обращаю ваше внимание на то, что знак ^ внутри квадратных скобок обозначает отрицание, не путайте!

Обратные связи в mod_rewrite

$n – это наша «переменная» в круглых скобках, о них мы уже говорили. Работает для RewriteRule.

%n – то же самое, только в RewriteCond. RewriteCond мы ещё не рассматривали, он у нас впереди.

Итак, если RewriteRule – это наши правила преобразования URL, то RewriteCond – это условие, аналог if в PHP. RewriteCond нужно в ситуациях, когда вам необходимо выполнить URL преобразование (RewriteRule) только при выполнении какого-то условия.

У сервера есть свои собственные переменные, которые мы можем использовать в наших условиях RewriteCond:

HTTP заголовки: 
HTTP_USER_AGENT
HTTP_REFERER
HTTP_COOKIE
HTTP_FORWARDED
HTTP_HOST
HTTP_PROXY_CONNECTION
HTTP_ACCEPT REMOTE_ADDR

Соединение и запрос:

REMOTE_HOST
REMOTE_USER
REMOTE_IDENT
REQUEST_METHOD
SCRIPT_FILENAME
PATH_INFO
QUERY_STRING
AUTH_TYPE

Внутри серверные:

DOCUMENT_ROOT
SERVER_ADMIN
SERVER_NAME
SERVER_ADDR
SERVER_PORT
SERVER_PROTOCOL
SERVER_SOFTWARE

Системные:

TIME_YEAR
TIME_MON
TIME_DAY
TIME_HOUR
TIME_MIN
TIME_SEC
TIME_WDAY
TIME

Специальные:

API_VERSION
THE_REQUEST
REQUEST_URI
REQUEST_FILENAME
IS_SUBREQ

Синтаксис применения серверных переменных таков:

%{переменная}

Давайте составим наше первое условие:

RewriteCond %{HTTP_USER_AGENT} ^Mozilla.* RewriteRule … 

Если посетитель зашёл с браузера Mozilla Firefox, то выполняем следующее правило. Как видите, в отличие от PHP мы не используем фигурные скобки для обрамления нашего правила, которое выполнится, если условие TRUE.

RewriteCond позволяет использовать операторы сравнения: < (меньше), > (больше), = (равно). Также есть специальные значения, например:

  • -d (является ли каталогом)
  • -f (является ли файлом)
  • -s (является ли файлом с ненулевым размером)
  • ! – отрицание.

Флаги

  • nocase|NC – можно писать либо nocase, либо NC, это одно и то же, обозначает регистро-независмость. То есть мы можем больше не писать:
  • RewriteRule ^useful/[a-zA-Z]

    Вместо этого написать так:

    RewriteRule ^useful/[a-z] [NC]
  • ornext|OR – если это, либо следующее условие TRUE, то выполняем RewriteRule. Пример:
  • RewriteCond %{REMOTE_HOST} ^host1.* [OR] RewriteCond %{REMOTE_HOST} ^host2.* [OR] RewriteCond %{REMOTE_HOST} ^host3.* RewriteRule … 
  • Last|L – последнее правило. Если правило применилось, то правила, расположенные ниже по коду, не сработают.
  • next|N – некий аналог continue. Если правило применилось, заставляет отыгрывать все правила с самого начала, но при этом с уже преобразованной строкой.
  • redirect|R – редирект. По умолчанию 302. Можно указать другой код редиректа, например:
  • [R=301]

  • forbidden|F – URL становится запрещённым.
  • gone|G – посылает 410 ответ сервера.
  • chain|C -связь. Если правило не сработало, то связанные с ним правила тоже автоматически не сработают.
  • type|T – MIME-тип. Принудительное выставление типа файла. Можно выдавать одно расширение файла за другое 🙂 Например, лежат у нас файлы с расширением .zip, а на самом деле это картинки, так вот чтобы отдавать эти файлы как картинку(.png, .gif и тд.), можно использовать данный флаг.
  • skip|S – пропустить следующее правило, можно указывать сразу несколько, например:
  • [S=2]
  • env|E=VAR:VAL – установить переменную окружения.
  • cookie|CO – послать куки.

Если нужно поставить одновременно несколько флагов, ставим их через запятую, например:

[NC,L]

Как вы уже могли догадаться, mod_rewrite можно использовать не только для ЧПУ, но и для многих других интересный целей, например, клоакинга – это метод чёрного SEO, когда по одному и тому же адресу посетителям отдаётся одна страница, а поисковым роботам совершенно другая. Ну и под конец статьи, я покажу вам живой пример использования всего написанного выше и как же это всё работает взаимодействуя с нашим PHP.

site-on.net

  1. Общие положения.
    1. Настоящая Политика конфиденциальности персональных данных (далее — Политика) действует в отношении всех персональных данных, которую компания Keengo (далее – Компания), может получить от пользователя (лица, заполнившего форму обратной связи, использующего другие сервисы официального сайта keengo.ru (далее – Сайт)), в частности в ходе: отправки отзывов или вопросов, заказа услуг, участия в рекламных и/или маркетинговых кампаниях или акциях и/или ином взаимодействии (далее – Услуги).
    2. Заполняя форму обратной связи и нажимая кнопку «Согласен/на», расположенную на странице Сайта, на которой размещена форма обратной связи, а равно указывая свои персональные данные при использовании других сервисов Сайта, пользователь выражает согласие с настоящей Политикой и указанными в ней условиями обработки и передачи его персональных данных. Согласие Пользователя на предоставление, обработку и передачу его Персональных данных Компании в соответствии с Политикой является полным и безусловным.
    3. Посетителям Сайта следует воздержаться от заполнения формы и/или от использования других сервисов Сайта в случае несогласия (полного или частичного) с Политикой, а равно несогласия предоставить персональные данные.
    4. Согласие, даваемое пользователем, включает в себя согласие на сбор, систематизацию, накопление, хранение, уточнение (обновление, изменение), использование, занесение в базы данных (в том числе электронные) Компании, передачу внутри Компании другим отделам и подразделениям или поставщику услуг, обязующегося выполнять условия договора о защите персональных данных, в целях рассылки информационных материалов и/или в рекламных целях (в том числе рассылку приглашений на мероприятия, проводимые/организованные Компанией), трансграничную передачу, блокирование, обезличивание, уничтожение персональных данных.
    5. Согласие, даваемое пользователем, распространяется на следующие персональные данные: фамилия, имя, отчество, адрес электронной почты, должность, наименование организации, в которой работает пользователь, контактный телефон.
    6. Срок действия согласия пользователя является неограниченным, однако, пользователь вправе в любой момент отозвать настоящее согласие путём направления письменного уведомления на адрес электронной почты: info@keengo.ru, с пометкой «отзыв согласия на обработку персональных данных».
  2. Персональные данные пользователей, которые получает и обрабатывает Компания.
    1. В рамках настоящей Политики под персональными данными пользователя понимаются персональные данные, которые пользователь предоставляет о себе самостоятельно при заполнении формы обратной связи на Сайте, при использовании других сервисов Сайта, при регистрации (создании учётной записи) на Сайте или в процессе использования услуг, предоставляемых Компанией. Соответствующая информация явно обозначена, к ней, в частности отнесены: фамилия, имя, отчество, адрес электронной почты, должность, наименование организации, в которой работает пользователь, контактный телефон. Иная информация предоставляется пользователем на его усмотрение.
    2. Компания исходит из того, что пользователь представляет достоверные персональные данные, а также, что пользователь имеет право предоставить персональные данные.
  3. 1С Битрикс.
    1. Компания использует средство 1С Битрикс для сбора сведений об использовании Сайта, таких как частота посещения Сайта пользователями, посещенные страницы и сайта, на которых были пользователи до перехода на данный Сайт. 1С Битрикс собирает только IP-адреса, назначенные пользователю в день посещения данного Сайта, но не имя или другие идентификационные сведения.
    2. 1С Битрикс размещает постоянный cookie-файл в веб-браузере пользователя для идентификации в качестве уникального пользователя при следующем посещении данного Сайта. Этот cookie-файл не может использоваться никем, кроме 1С Битрикс. Сведения, собранные с помощью cookie-файла, будут храниться на серверах, находящихся в Российской Федерации.
    3. Компания использует сведения, полученные через 1С Битрикс, только для обработки и хранения персональных данных.
  4. Цели обработки персональной информации пользователей.
    1. Компания обрабатывает только те персональные данные, которые необходимы для оказания услуг.
    2. Персональную информацию пользователя Компании может использовать в следующих целях:
      1. Идентификация стороны в рамках оказания услуги.
      2. Рассылка рекламных и/или маркетинговых материалов Компании, рассылка приглашений на мероприятия, конференции, выставки, проводимые и/или организуемые Компанией, проведение телемаркетинговых компаний.
      3. Проведение статистических и иных исследований, на основе обезличенных данных.
  5. Передача персональных данных пользователя третьим лицам.
    1. В отношении персональных данных пользователя сохраняется ее конфиденциальность, кроме случаев обработки персональных данных, доступ неограниченного круга лиц к которым предоставлен пользователем либо по его просьбе.
    2. Компания вправе передать персональную информацию пользователя третьим лицам в следующих случаях:
      1. Пользователь предоставил свое согласие на такие действия.
      2. Передача персональных данных организациям, которые оказывают услуги Компании по рассылке рекламных и/или маркетинговых материалов, организации и проведению мероприятий, конференций, выставок, телемаркетингу, обзвону потенциальных клиентов Компании.
      3. Передача необходима для достижения целей, осуществления и выполнения функций, полномочий и обязанностей, возложенных законодательством Российской Федерации на Компанию.
  6. Меры, применяемые для защиты персональных данных пользователей.
    1. Компания принимает необходимые и достаточные организационные и технические меры для защиты персональных данных пользователя от неправомерного или случайного доступа, уничтожения, изменения, блокирования, копирования, распространения, а также от иных неправомерных действий с персональными данными третьих лиц.
  7. Права и обязанности пользователя.
    1. Компания предпринимает разумные меры для поддержания точности и актуальности, имеющихся у Компании персональных данных, а также удаления устаревших и других недостоверных или излишних персональных данных, тем не менее, Пользователь несет ответственность за предоставление достоверных сведений, а также за обновление предоставленных данных в случае каких-либо изменений.
    2. Пользователь может в любой момент изменить (обновить, дополнить, блокировать, уничтожить) предоставленную им персональную информацию или её часть, а также параметры её конфиденциальности путем обращения в Компанию.
    3. Пользователь вправе в любой момент отозвать согласие на обработку Компанией персональных данных путём направления письменного уведомления на электронный адрес: info@keengo.ru с пометкой «отзыв согласия на обработку персональных данных», при этом отзыв пользователем согласия на обработку персональных данных влечёт за собой удаление учётной записи пользователя с Сайта и баз данных Компании, а также уничтожение записей, содержащих персональные данные, в системах обработки персональных данных Компании.
    4. Пользователь имеет право на получение информации, касающейся обработки его персональных данных Компанией.

keengo.ru

Добрый день, читатель! Или вечер… не важно, главное что ты заглянул) Сегодня мы продолжим разрабатывать нашу CMS и реализуем такую штуку, как ЧПУ. О том что это, зачем нужно и как работает — все это разберем и на выходе получим новый модуль для нашей системы. Полны вперед!

Итак, для начала, что же такое ЧПУ? Нет, это не «числовое программное управление», как некоторые могли подумать (хотя они, в общем-то, и правы), а СЕМАНТИЧЕСКИЙ адрес. Почему тогда ЧПУ? Просто кто-то когда-то подумал, что «семантический адрес сайта» звучит как-то сложно, и решил назвать «ЧеловекоПонятный Урл». У этого термина есть еще несколько альтернативных названий, но ЧПУ — самый распространенный.

Теперь немного о том, в чем суть использования ЧПУ.
Несемантический адрес выглядит примерно вот так:

domain.ru/index.php?module=news&action=all&page=4

Теперь посмотрите на тот же адрес, но уже с семантическим видом:

domain.ru/news/all/page/4

Думаю такой адрес вам больше понравилось бы видеть в своей адресной строке (хотя например мне, по большому счету, плевать как выглядят ссылки на том или ином сайте, если конечно он не представляет для меня технический интерес). Как видно из примеров, при использовании ЧПУ длинна ссылки значительно сокращается (в основном, но бывают исключения), сам адрес выглядит более эстетично и напоминает обычную структуру файловой системы. Такой вид позволяет понимать, чего ожидать от этой страницы — в нашем случае мы просматриваем все новости на 4й странице. в качестве бонуса уходит имя исполняемого файла и имена переменных, которые он использует — какая-никакая, а защита.

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

Итак, задачи на сегодня:

  • реализовать понимание движком семантических ссылок
  • сделать это в виде модуля
  • работа модуля не должна сказываться на работе логики CMS
  • при включении семантических урл, обыкновенные ссылки должны тоже работать
  • проверить все это дело на простеньких примерах

Пожалуй начнем. Для начала, мы должны создать файл с именем .htaccess, да, именно такое имя, по сути имени нет, только расширение. Это файл конфигурации веб-сервера для конкретного домена. Он нам нужен чтобы описать правило перезаписи, которое послужит основой для работы нашего модуля. Итак, в созданный в корне сайта файл .htaccess пишем следующее:

<IfModule mod_rewrite.c> RewriteEngine On Options +FollowSymlinks RewriteBase /   RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php [L,QSA] </IfModule>

простое правило, думаю оно вполне понятно. Теперь, когда веб-сервер работает как нужно нам, мы можем приступать к написанию модуля ЧПУ. Начнем конечно же с, уже стандартной проверки и объявления класса, назовем его surl (Semantic URL) и заполним его основным кодом, который требуется для работы с нашим реестром:

if (!defined('_PLUGSECURE_')) {  die('Прямой вызов модуля запрещен!'); }  class surl{ 	 	private static $className = "ЧПУ";   	public static function getClassName() 	{		 		return self::$className;	 	} }

этот код нам знаком, понятен и является минимальным каркасом для любого модуля нашей системы. Думаю на этом этапе все понятно. Теперь приступим к функции, которая будет выполнять обработку адреса.
Я достаточно долго думал, смотрел кучу реализаций и комбинировал их так или иначе, но то, что получалось не решало всех поставленных задач, в частности — безопасного включения/отключения модуля, без влияния на систему и поддержку ссылок без семантики при включенных ЧПУ. Взяв самый более-менее годный код из того, что у меня получалось я решил, что его можно допилить до нужного результата. У меня вроде как получилось ? Я подумал, что имеет смысл несколько стандартизировать сам семантический УРЛ и пришел к следующему решению: все адреса нашей системы будут иметь две обязательных части и список параметров, которые могут и отсутствовать, в зависимости от потребностей того или иного скрипта.
Чтоб было понятней, урл будет иметь следующий вид:

ourdomain.ru/МОДУЛЬ/ДЕЙСТВИЕ/ПАРАМЕТР_1/ЗНАЧЕНИЕ_1/ПАРАМЕТР_2/ЗНАЧЕНИЕ_2/ПАРАМЕТР_N/ЗНАЧЕНИЕ_N

Возможно, скорее даже точно, это не самый лучший вариант, но для основной работы самих ЧПУ нам это вполне подходит. Параметр МОДУЛЬ — это не те модули, которые мы сейчас разрабатываем. Это модули внешнего функционала, например модуль новостей или регистрации пользователя. Чтоб вы не путались в будущем. А теперь, как я это реализовал на PHP, поехали.

После объявления переменой с именем класса пишем одну единственную функцию — parseUrl, которая принимает на вход лишь один параметр $type, сообщающий о состоянии ЧПУ: 1 — включен, 0 — выключен.Добавим его чуть позже, а пока начинаем писать саму функцию.

Объявляем функцию и сразу создаем массив, который будет возвращать наша функция с набором наших данных.

public static function parseUrl($type) { 	$data = array(); }

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

if($type == 1) 	{	 		if ($_SERVER['REQUEST_URI'] != '/') 		{ 			$url_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); 			$uri_parts = explode('/', trim($url_path, ' /'));

Если запрашиваемый адрес отличен от корня сайта, парсим его кусок с параметрами и разбиваем по знаку косой черты (слеш). Теперь нам нужно проверить количество параметров в семантическом адресе, их у нас должно быть обязательно четное количество. Минимум — два параметра МОДУЛЬ и ДЕЙСТВИЕ + неограниченное количество пар ПАРАМЕТР и ЗНАЧЕНИЕ. То есть, если количество данных в адресе нечетно, то это значит о том что адрес не верный, а так же еще и то, что запрос возможно идет по несемантическому адресу. Этот момент поясню: чуть выше, после парсинга адреса, мы разбивали его на части и записывали в массив. Разбивали мы по слешу, но что если адрес запрашивается через обычные $_GET параметры? В таком случае в массиве после разбивки мы получим одну запись, например:

index.php?module=reg&action=newuser

да, тут есть два необходимых параметра МОДУЛЬ и ДЕЙСТВИЕ, но т.к. они не в семантическом виде, наша операция разбивки найдет только один слеш — после имени домена — и все кинет в одну ячейку массива. Надеюсь мне удалось донести свою мысль. Если нет — пишите в комменты, помогу разобраться; а пока продолжим. У нас получается всего одна ячейка, 1 — число нечетное, а значит можно попробовать распарсить данные альтернативным методом, при условии что есть что парсить.

if (count($uri_parts) % 2)  { 	$uri_parts = explode('&', trim($url_path, ' /')); 	if(isset($_GET['module']) & isset($_GET['action'])) 	{ 		$data['module'] = $_GET['module']; 		$data['action'] = $_GET['action']; 		unset($_GET['module']); 		unset($_GET['action']); 		foreach ($_GET as $key => $value) 		{ 			$data['params'][$key] = $value; 		} 	} 	else 	{ 		die('Запрос не может быть обработан.'); 	} }

Если после целочисленного деления на 2 мы получили остаток, отличный от нуля, то значит количество параметров нечетное, разбиваем то, что есть в массиве по знаку амперсанд (&) и, если в массиве что-то есть, мы получим ассоциативный массив вида ПЕРЕМЕННАЯ=ЗНАЧЕНИЕ. Мы договорились что обязательно должны присутствовать 2 переменные, значит если их нет, то и нет смысла обрабатывать этот запрос.

Так, проверили, все есть, значит записываем значения в соответствующие ячейки и удаляем эти данные из массива $_GET. После удаления параметров МОДУЛЬ и ДЕЙСТВИЕ, все, что остается — это список параметров для запрашиваемой страницы. Их тоже записываем в наш массив данных но в отдельную ячейку. Ну а если запрос не проходит наши проверки, то и не паримся его обрабатывать.

С альтернативным методом все, теперь возвращаемся к ЧПУ. Если запрос имеет четное количество параметров то первый из них — это МОДУЛЬ, а второй — ДЕЙСТВИЕ. Просто вынимаем их по очереди, удаляя из исходного массива. После этого, в нашем исходном массиве, если что-то и осталось, то это наши параметры для конкретной страницы. Записываем их тоже в наш конечный массив. Все это выглядит следующим образом:

else { 	$data['module'] = array_shift($uri_parts); 	$data['action'] = array_shift($uri_parts);  	for ($i=0; $i < count($uri_parts); $i++)  	{ 		$data['params'][$uri_parts[$i]] = $uri_parts[++$i]; 	} }

Осталось только закрыть самую первую операцию if в нашей функции и вернуть полученный массив с данными:

	} 	return $data; }

Вот и все, ЧПУ уже будет работать, а если кто-то решит по старинке обратиться к сайту - попадет на альтернативный парсер. Не знаю как вам, а мне понравилась такая реализация. Единственное что еще осталось сделать - написать обработчик, который будет срабатывать, если ЧПУ отключены. Тут ничего сложного: у нас уже есть нужный код выше - тот самый альтернативный обработчик, который с этим справится. Не буду повторно его расписывать, он практически идентичен, смотрите сами:

else { 	if ($_SERVER['REQUEST_URI'] != '/') 	{ 		$url_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); 		$uri_parts = explode('&', trim($url_path, ' /')); 		if(isset($_GET['module']) & isset($_GET['action'])) 		{ 			$data['module'] = $_GET['module']; 			$data['action'] = $_GET['action']; 			unset($_GET['module']); 			unset($_GET['action']); 			foreach ($_GET as $key => $value) 			{ 				$data['params'][$key] = $value; 			} 		} 		else 		{ 			die('Запрос не может быть обработан.'); 		} 	} 	return $data; }

Ну как? Говорю же, тот же самый код ? Разница лишь в том, что мы не пытаемся разбить строку по слешам, а сразу разбиваем по амперсанду, вот и все. Вот теперь модуль работы с ЧПУ можно назвать готовым, можно приступать к проверкам, но для начала давайте добавим одну переменную в наш с вами конфиг:

public static $s_url = 1;

Эта переменная будет отвечать у нас за режим работы модуля: 1 - модуль пытается обработать ЧПУ, 0 - обрабатываются обычный, несемантический адрес (хотя по сути, если вы заметили из кода - функция схавает любое число или символ, отличный от единицы, но давайте договоримся использовать 0).

Теперь приступаем к тестам. Открываем наш файл index.php и подключаем новоиспеченный модуль к нашему реестру, сразу после подключения модуля базы данных:

$registry->surl = '/core/surl.php';

Теперь можем проверить как принял наш реестр нового бойца - зайдем на localhost, или другой локальный домен (если вы меняли настройки сервера). Если все пошло как надо, то в списке подключенных модулей мы увидим модуль с именем "ЧПУ". Есть? Замечательно! Теперь проверим непосредственно работу модуля surl. В самый конец файла index.php пишем следующий код:

echo "
"; echo "Проверка работы ЧПУ:
"; $chpu_data = $registry->surl->parseUrl($registry->config::$s_url); foreach ($chpu_data as $key => $value) { if($key != 'params') { echo $key . ': ' . $value . '
'; } else { echo "PARAMS:
"; foreach ($value as $key2 => $value2) { echo $key2 . ': ' . $value2 . '
'; } } }

воспользовавшись нашей функцией parseUrl из модуля surl мы получаем массив с данными из URL-запроса. Сохраните файл index.php и откройте локальный домен. Данных никаких нет - и после строки "Проверка работы ЧПУ:" вы ничего не увидите. А теперь попробуйте вбить, например такой адрес:

localhost/news/show/page/11/

Ну как?) Теперь попробуем альтернативный парсер и запросим ту же страницу, но в формате get:

localhost/index.php?module=news&action=show&page=11

Если все сделано правильно, то класс отработает без ошибок и при запросе обоих ссылок вы увидите, что функция правильно обрабатывает как ЧПУ, так и простые url с get-параметрами. Если отключить ЧПУ в конфге, то будет срабатывать сразу альтернативный парсер.
Итак, что же в итоге:
модуль surl понимает как человекопонятные УРЛы, так и классические ссылки с get-параметрами одинаково; можно отключить обработку ЧПУ и работать только с get-запросами - это не повлияет на логику нашей системы. Поставленные в начале статьи задачи выполнены - я считаю это очередной успешный шаг, давайте себя с этим поздравим ;-P

Конечно, этим все не ограничется. Мы научили нашу CMS только понимать семантические ссылки. Нужен еще как минимум какой-то обработчик, который приняв данные МОДУЛЬ/ДЕЙСТВИЕ/ПАРАМЕТРЫ подгрузит нужный модуль, который запустит необходимое действие с полученными параметрами. Вдобавок, я хочу реализовать так называемые алиасы статичных (не обязательно?) страниц.

По задумке каждая страница будет иметь алиас и храниться он будет в соответствующей таблице БД, а доступ к ней будет возможен как по алиасу, так и по обычной ссылке с get-параметрами. Уф, что-то я вперед уже забегаю, пора остановиться. Кстати, было бы интересно послушать ваши варианты подобной реализации в комментариях, не стесняйтесь. А пока, на этом закончим сегодня. Удачи и до встречи в следующих материалах!

P.S. К сожалению не было возможности сделать скриншоты проверок, поэтому прикрепляю исходник. Прошу только не копипастить его, а прочитать и понять каждую его строчку. Если что-то непонятно - комментарии всегда открыты, о каждом новом я получаю уведомление, так что ни один не будет пропущен (если это не спам конечно).
P.P.S. Как могли заметить - эта статья снова без фотошапки. Пока повисит так, пока ко мне не вернется моя ненаглядная с отдыха со своим Никоном ?

Скачать исходник модуля surl.php

fussraider.ru

Решил написать эту заметку, потому как надоело отвечать 100500 раз одно и то же на ВиО.

Многие начинающие веб-программисты рано или поздно сталкиваются с задачей внедрения в свой сайт человеко-понятных линков (ЧПУ). До внедрения ЧПУ все ссылки имеют вид /myscript.php или даже /myfolder/myfolder2/myscript3.php, что тяжело для запоминания и ещё хуже для SEO. После внедрения ЧПУ линки принимают вид /statiya-o-php или даже на кириллице /статья-о-пхп.

Кстати о SEO. Человекопонятные линки на САМОМ деле придумали не для удобного запоминания, а в основном для повышения индексируемости сайта, потому что совпадение поискового запроса и части URL даёт хорошее преимущество в рейтинге поиска.

Эволюция начинающего PHP-программиста может быть выражена следующей последовательностью шагов:

  1. Размещение plain-PHP кода в отдельных файлах и доступ к этим файлам через линки вида /myfolder/myscript.php
  2. Понимание, что все скрипты имеют значительную часть общего (например, создание подключения к БД, чтение конфигурации, запуск сессии и проч.) и как следствие создание общей начальной точки «входа», некоторого скрипта, который принимает ВСЕ запросы, а потом выбирает — какой внутренний скрипт подключить. Обычно этот скрипт имеет имя index.php и лежит в корне, вследствие чего все запросы (они же URLы) выглядят так: /index.php?com=myaction&com2=mysubaction
  3. Необходимость внедрения роутера и переход к человекопонятным линкам.

Замечу, что между пунктами 2 и 3 большинство программистов делают очевидную ошибку. Я не ошибусь, если назову это значением около 95% программистов. Даже большинство известных фреймворков содержат эту ошибку. И заключается она в следующем.

Вместо того, чтобы реализовывать принципиально новый способ обработки линков, ошибочно делается концепция «заплаток и редиректов» на базе .htaccess, которая заключается в том, чтобы с помощью mod_rewrite создавать множество правил редиректа. Эти строки сравнивают URL с каким-либо регулярным выражением и при совпадении расталкивают выуженные из URL значения по GET-переменным, в дальнейшем вызывая всё тот же index.php.

  #Неправильный метод ЧПУ    RewriteEngine On  RewriteRule ^/users/(.+)$ index.php?module=users&id=$1 [QSA]    #....Ещё куча подобных правил...  

У данной концепции множество недостатков. Один из них — трудность создания правил, большой процент человеческих ошибок при добавлении правил, которые сложно выявить, но они приводят к ошибке сервера 500.

Другой недостаток в том, что часто правится по сути конфига сервера, что само по себе нонсенс. И если в Apache конфиг можно «пропатчить» с помощью .htaccess, то в популярном nginx такой возможности нет, там всё находится в общем файле конфигурации в системной зоне.

И ещё один недостаток, вероятно, наиболее важный, что при таком подходе невозможно динамически конфигурировать роутер, то есть «на лету», алгоритмически менять и расширять правила выбора нужного скрипта.

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

Суть заключается в том, что начальный запрос всегда хранится в переменной $_SERVER[‘REQUEST_URI’], то есть его можно считать внутри index.php и разобрать как строку средствами PHP со всеми обработками ошибок, динамическими редиректами и проч и проч.

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

  RewriteEngine On  RewriteCond %{REQUEST_FILENAME} !-f     #Если файл не существует  RewriteCond %{REQUEST_FILENAME} !-d    #И если папка не существует  RewriteRule ^.*$ index.php [QSA,L]  

Причём это правило можно разместить как в .htaccess, так и в основном файле конфигурации Apache.

Для nginx соответствующее правило будет выглядеть вот так:

  location / {   if (!-e $request_filename) {   rewrite ^/(.*)$ /index.php last;   }  }  

Всё просто.

Теперь рассмотрим кусок кода PHP в index.php, который анализирует ссылки и принимает решение — какой скрипт запускать.

В общем случае ссылка из $_SERVER[‘REQUEST_URI’] выглядит так

/часть1/часть2/часть3

Первое, что приходит в голову — разбить её с помощью explode(‘/’, $uri) и сделать сложный роутер на основе switch/case, анализирующий каждый кусок запроса. Не делайте этого! Это сложно и в итоге приводит код в ужасный непонимабельный и неконфигурабельный вид!

Я предлагаю более лаконичный способ. Лучше не описывать словами, а сразу показать код.

  <?php    /**   * Sitemap (можно перенести в отдельный файл)   */  $GLOBALS['sitemap'] = array (   '_404' => 'page404.php',   // Страница 404</span>   '/' => 'mainpage.php',   // Главная страница   '/news' => 'newspage.php',   // Новости - страница без параметров   '/stories(/[0-9]+)?' => 'storypage.php',  // С числовым параметром   // Больше правил  );    // Код роутера  class uSitemap {   public $title = '';   public $params = null;   public $classname = '';   public $data = null;     public $request_uri = '';   public $url_info = array();     public $found = false;     function __construct() {   $this->mapClassName();   }     function mapClassName() {     $this->classname = '';   $this->title = '';   $this->params = null;     $map = &$GLOBALS['sitemap'];   $this->request_uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);   $this->url_info = parse_url($this->request_uri);   $uri = urldecode($this->url_info['path']);   $data = false;   foreach ($map as $term => $dd) {   $match = array();   $i = preg_match('@^'.$term.'$@Uu', $uri, $match);   if ($i > 0) {   // Get class name and main title part   $m = explode(',', $dd);   $data = array(   'classname' => isset($m[0])?strtolower(trim($m[0])):'',   'title' => isset($m[1])?trim($m[1]):'',   'params' => $match,   );   break;   }   }   if ($data === false) {   // 404   if (isset($map['_404'])) {   // Default 404 page   $dd = $map['_404'];   $m = explode(',', $dd);   $this->classname = strtolower(trim($m[0]));   $this->title = trim($m[1]);   $this->params = array();   }   $this->found = false;   } else {   // Found!   $this->classname = $data['classname'];   $this->title = $data['title'];   $this->params = $data['params'];   $this->found = true;   }   return $this->classname;   }  }  $sm = new uSitemap();  $routed_file = $sm->classname; // Получаем имя файла для подключения через require()  require('app/'.$routed_file); // Подключаем файл    // P.S. Внутри подключённого файла Вы можете использовать параметры запроса,  // которые хранятся в свойстве $sm->params    

Несмотря на то, что код довольно длинный, он прост логически. Мне не хочется его объяснять, я считаю любой код на PHP самообъясняющим, если он правильно написан. Учитесь читать код.

epsiloncool.ru


You May Also Like

About the Author: admind

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

Adblock
detector