Pull to refresh

Comments 153

«Я думаю, улучшение производительности будет ощутимо.»
А где доказательства? Тесты?

"
RewriteRule ^(.*)$ index.php?param=$1 [QSA,L]
И вот это:
RewriteRule ^/pages/([0-9A-z_]{1,64}).html$ index.php?mod=Pages&page_link=$1 [QSA,L]
"

Сравние эти реврайты на строке /pages/1.htm
Второй реврайт подавится

А если админ отключил мод_реврайт вся навигация через него идет лесом.

«неправильноые» -> неправильные
>> А где доказательства? Тесты?
В данном случае вы придираетесь. Начнем хотя-бы с того, что при обработке запроса через mod_rewrite вы лишаетесь одного звена в цепи — скриптового языка. Конечно понятно, что напортачить можно везде, но уменьшение цепи может только положительно играть на производительности системы, или не так?

>> Второй реврайт подавится
Вам трудно это предположить и сделать .htm|.htm? Тогда я затрудняюсь вам что-либо объяснять.

>> А если админ отключил мод_реврайт вся навигация через него идет лесом.
Я не думаю, что админ может быть настолько невменяем. По крайней мере из всех моих знакомых админов, работающих в хостинг-компаниях не было еще ни одного, который бы жаловался на mod_rewrite и отключал его из каких-либо своих соображений.

>> «неправильноые» -> неправильные
Спасибо, сейчас исправлю.
Вы меня заинтриговали =) Приду домой проведу пару тестов производительности :)
Мы не лишаемся одного звена в цепи, мы переносим его в реврайт. То, что раньше делали регулярки в пхп например, теперь делает регулярка в мод реврайте.

Мне не трудно предположить. Это я все к тому, что регулярное выражение разрастется довольно сильно, если предусматривать разные варианты.

Я воспринимаю, что вся ваша идея в том, что мы перенесли выбор модуля в реврайт. Все равно нам надо будет парсить некоторые параметры в самом скрипте. POST, GET. Все равно парсить будем. Поэтому я и прошу обоснований, почему этот перенос в реврайт выйдет быстрее, чем та же регуляркаа в пхп.
Если вы используете абсолютный реврайтинг по типу первого примера — вы именно лишаетесь звена, т.к. обращение в самому mod_rewrite всеравно будет и процессорное время и клочок памяти для его работы тоже будут выделены.

Соответственно, 1. Мы лишаемся лишнего звена в виде регулярок в скриптовом языке.
2. Работу над регулярками мы возлагаем на mod_rewrite

Если вас и это не устраивает — я постараюсь составить аналогичные по своей сути тесты производительности и выложу сюда результаты тестирования.
именно на тесты я и хочу взглянуть. мне нет нужды пытаться в чем-то опровергнуть ваши утверждения, я хочу докопаться до истины и узнать как оно на самом деле.
Хорошо. Ближе к вечеру постараюсь придумать адекватные тесты и дополню топик результатами тестирования производительности.
и без тестов ясно что с mod_rewrite диспетчеризация запросов будет работать быстрее.
подумайте сами:
— правила mod_rewrite начинают работать еще ДО того как апач передал управление Php скрипту. и далее при совпадении одного из правил — апач вызовет php скрипт с конкретными входными параметрами. ив самом скрипте НЕТ необходимости вычислять что запросил пользователь! Можно просто запустить соответствующий контроллер или функцию…
— не секрет что публичному серверу приходится обрабатывать Кучу невалидных запросов (ошибочные перенаправления с других серверов, сканирование сервера различными червями, устаревшие ссылки и т.д.). mod_rewrite поможет все эти запросы сразу отдавать статической странице ошибок, НЕ ЗАПУСКАЯ PHP вообще…
— кстати, хостинга где нет mod_rewrite ) я давно уже не встречал )
Выложил тест. Он не уповает на объективность, но сходу что-то более объективное мне не придумалось. Если у вас есть еще какие-либо варианты Test Case'ов — описывайте, с удовольствием протестирую и их.
Это тест для универсального шаблона. В разных контроллерах параметры качественно и количественно могут различаться
Ну так что же вы? Постарайтесь дать мне какой-либо адекватный пример, который можно сравнить — и мы получим более-менее живой результат.
Почитайте комментарии :) Тут несколько примеров уже привели.
Например, ведь Ваш вариант не обработает случай запуска с другим числом параметров :)
для обработки этих самых Других параметров — нужно написать логику обработки, на Реврайте или внутри скрипта…

так что ваш довод пуст!
Читайте внимательнее комментарии!
Разбирая параметры скриптом, мы не обрабатываем их все сразу, как Реврайт, а постепенно углубляемся внутрь, передавая обработку логики заинтересованным контроллерам, а не кому-то одному (т.е. не складируем логику в одно место, ибо это бессмысленно)
реврайт не занимается логикой!
он только разруливает урлы.
логику вы конечно опишите внутри контроллеров…
я как раз про логику обработки. Которую Вы вынуждены накапливать в правилах.
Попробуйте «разруливать» УРЛы с переменным числом параметров без увеличения числа регэкспов (ну или хотя бы без падения производительности), да еще и невалидные УРЛы обработайте корректно (повторюсь в очередной раз, это все-таки не мелочи)
я ничего там не накапливаю ))
у меня как раз все нормально:

Реврайт занимается своим делом -> разбирает урлы и вызывает соответсвующие скрипты…
Скрипты Пхп занимается своим -> отрабатывают какую угодно логику…

а вот вы засунули Обработку Урлов в скрипты… и доказываете что так и должно быть)
смешно
Да с какого перепугу Реврайт должен знать всю архитектуру системы (когда, кого и куда отправить)? Сами подумайте, добавили контроллер -> надо переделать htaccess, не смешно разве?
Реврайт не должен знать и он незнает )))
Он просто транслирует — красивые Урлы переделывает — В понятные и родные для ПХП…
что происходит далее, его неволнует…

>добавили контроллер -> надо переделать htaccess
не надо. Контроллеры работают по общему принципу. Именование разделов и Роутинг «на нормальном сайте» подчиняется логике.
Поэтому — ОДИН РАЗ пишется 10 правил в htaccess
а потом добавляйте хоть сотни Контроллеров… htaccess трогать уже не надо…
А зачем переделывать красивые УРЛы, если их пхп и так поймет (после обработки в index'е)?
Ведь по сути, mod_rewrite делает просто разбор введенных параметров. Так ведь? Он не направляет к другому скрипту — все равно ведь все идет на index.php (ну или на error.php, если все же Вы хотите фиксировать инвалидный УРЛ без скрипта). В чем смысл-то? Использовать регэкспы вне пхп?
Единственное, что полезно при «красивых УРЛах» — это возможность отброса или добавления чего-то к УРЛу (что бывает часто при ЧПУ) на общих основаниях.
>А зачем переделывать красивые УРЛы, если их пхп и так поймет (после обработки в index'е)?
вот именно. Чтоб Пхп понял ему еще нужно будет запускать написанный вами парсер и роутер ( функционал которых значительно уступает модулю Реврайт)
и только потом начнет работать Скрипт отрабатывающий Бизнес-логику.
налицо велосипед!
> Ведь по сути, mod_rewrite делает просто разбор введенных параметров
Не только разбор! Реврайт может делать еще кучу нужных нужных действий над Урлами. Ваш самописный скрипт нуждо будет постоянно дописывать, при возникновении новых требований и условий для Урлов сайта. А с Реврайтом будет достаточно добавлять правила И ВСЕ! дописывать или переписывать чтото для этого не надо будет.
>>вот именно. Чтоб Пхп понял ему еще нужно будет запускать написанный вами парсер и роутер ( функционал которых значительно уступает модулю Реврайт)
и только потом начнет работать Скрипт отрабатывающий Бизнес-логику.
налицо велосипед!

Роутер и так есть. Если мы говорим о фреймворках. Насчет уступает функционалу — не надо так :) Скрипт позволяет вносить логику, а реврайт тупо следует внесенным правилам. Причем парсер — это даже не регэксп, а explode(). И никаких велосипедов.

>> Реврайт может делать еще кучу нужных нужных действий над Урлами. Ваш самописный скрипт нуждо будет постоянно дописывать, при возникновении новых требований и условий для Урлов сайта. А с Реврайтом будет достаточно добавлять правила И ВСЕ! дописывать или переписывать чтото для этого не надо будет.

Какие-то действия оставить в реврайте (я не отрицаю его полезности!). Вот только не очень представляю себе, какие изменения должны вынудить внести изменения в Роутер :)
Так а что показывает этот тест? В нем вы не пытаетесь доказать свою точку зрения, которую обозначили в начале статьи, иже на каждый URL сделать свое правило, сравнение скорости работы регулярок имеет к нашему спору очень косвенное отношение, да и к тому-же показало что PHP не координально в этом плане отстает, и разницей можно пренебречь.
1. Этот тест показывает, что в скорости работы МОЖНО выиграть путем работы с mod_rewrite БЕЗ PHP-парсера URL'ов. Это важно для очень критичных к нагрузкам приложений. И это обозначено в первом пункте статьи.
Не показывает, добавьте туда еще десяток-другой правил — тогда покажет.
В скриптовом языке URL можно обрабатывать не регулярками :) В скриптовом языке есть условные конструкции, если одно условие совпало — то половину из всех возможных условий уже можно не проверять и т.п. :)
даешь каждой странице сайта отдельный IF в фронт-котнтроллере!
А регулярка на каждую страницу это не отдельный IF?
не совсем так.
сначала выделяется логика адресации в каждом Разделе, а потом для каждого раздела пишется несколько регулярок, описывающих в Общем виде — его возможные подстраницы…
А, ну в php-скрипте с бесчисленным кол-вом вариантов обработки входящих данных так нельзя, только по отдельному ифу на страницу. Пишите тогда уж и логику сайтов регулярками, что вы себя мучите.
Ожидал чего-то революционного, а получилось как всегда. Я вот сразу после ознакомления с этим модом писал регекспы для переписывания строк, этот модуль по идее для этого и нужен.(судя по названию).

Так что практики как таковой я тут не увидел. Пишите дальше более интересные вещи про mod_rewrite может что-то интересное пролетит :)
Спасибо, постараюсь оправдать ваши ожидания в будущем.
В случае когда единственное правило переадресует запрос на скрипт:
* он будет значительно быстрее и лучше разбит внутри полноценного скриптового языка, с полным набором функций обработки строк
* фронтальный контроллер при этом можно определить как угодно, он все равно получит все запросы, какие сможет обработать — такие обработает, какие не сможет — выдаст страницу ошибки.
* данные при этом будут опять-же обработаны так как надо, без пирамид из регулярок.

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

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

С сотнями вы загнули. В любом случае URL-ов ограниченное множество. И разбить их на логические блоки, и затем обрабатывать их поблочно — кто же мешает? Это намного лучше, чем городить мегапарсер на PHP, который будет заниматься абсолютно той же задачей и решать абсолютно ту же проблему.

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

>>> * фронтальный контроллер при этом жестко завязан на файл с правилами, чтобы определить доп.страницу — нужно добавлять правило, сделать нефиксированный контроллер, который например обрабатывает альясы адресов сохраненные в БД — вообще нереально
Копать сюда: camaya.net/modrw ^_^

>>> чтобы указать более-менее нетривиальную последовательность входных параметров — нужно будет городить огромную регулярку, а как я уже писал в первом пункты — при обращении на последнее правило обрабатываться они будут все
Я еще не встречал задач, где требуются действительно «Огромные» регулярки. Может приведете пример? БЫло бы интересно.
Возьмите, например, электронный магазин, где для каждого продукта генерится урла, уснованная на его имени и именах категорий, в которых он расположен. В файле с правилами вы такой урл не разберете, естественно.
Приведите пример URL. Так будет понятнее.
Ну это громко сказано. Регуляркой можно всё что угодно распарсить, если есть хоть кокая-то логика. Другое дело, что если сначала заказчик захочет написать /catalog/subcatalog/super-goods.html, а потом СЕО-шники ему посоветуют положить этот товар просто в /super-goods.html. Такое на стороне скрипта решить можно, а через mod_rewrite уже вряд ли. Хотя не знаю, может rewrite map ещё живы. Впрочем, это тот же проброс инфы в скрипт, который возвращает путь к нужному файлу.
Хм. Мне кажется такой путь решения неправилен. Т.е. возлагать такие задачи на скрипт — неуместно. Я могу ошибаться, но я бы так никогда не поступил. И такое решение, да, имеет право на жизнь, но я бы не стал им пользоваться. Я всегда привык видеть перед глазами карту сайта и понимать, куда мой пользователь может пойти, а не разбираться, что же где и куда положено, и как это в конце концов нас привело не к товару, а на порносайт… ^_^
Ну я уже писл, что решение несколько спорное, но свой круг почитателей у него точно есть.
>… правилами вы такой урл не разберете,

Ну в смысле разобрать-то разберете, но толку это этого разбора никакого не будет — т.к. полюбому всю валидацию в скрипте делать придется.
1. Я просто встречал идеологов вашего подхода, и их регулярки с действительно сотням правил, в случае крупного проекта
2. Скорость обработки регулярок — может и разные вещи, но не координально, но опять-же, как я писал выше — в скрипте есть не только регулярки.
3. То что я откопал меня ужаснуло :) нет, это конечно тоже подход, но в случае изменения например параметров подключения к БД — это каждый раз их в конфиге апача исправлять? :) А если БД будет заменена на другую? Тоже в апач, и т.п.
4. Ну вы например предлагаете регулярками фильтровать входные POST-данные, в последнем проекте над которым я работал при добавлении документа было одних только дат 5 штук, дата публикации, дата аннотации, дата устаревания и т.п., причем дата устаревания не может быть меньше даты публикации, что тоже в регулярке нужно учесть, а всех параметров — порядка 20, по мне так просто написать эту регулярку — уже нетривиальная задача.

В любом случае этот подход — это вынесение скриптовой логики за пределы скрипта, в грамотно спроектированном скрипте любую логику можно изменить быстро и малой кровью, используя современные методологии программирования, в случае когда эта логика вынесена в mod_rewrite — нужно будет ручками переписать каждое правило.
Тьфу, насчет БД неправ, он задается как rewritemap отдельным файлом, но все равно это мало склоняет меня к вашему подходу, этот файл тоже нужно перегенерировать при изменении параметров БД, помимо основного файла конфигурации БД.
На самом деле идеология проста — использовать инструменты для того, для чего они предназначены.
1. В случае крупного проекта это уже не ошибка идеологов mod_rewrite, это скорее ошибка идеологов проекта. Я больше склоняюсь к такой позиции. Ибо при нормальном архитектурном планировании задач с регуляркой на сотню правил можно избежать.
2. Сейчас как раз занят тестами.
3. Я не говорил, что это правильный путь ^_~. Но он тоже возможен.
4. POST — данные и их фильтрация — отдельная задача, совершенно к mod_rewrite никак не относящаяся. И о фильтрации я говорил в плане управляющего GET-запроса. Соответственно, весь POST через mod_rewrite всегда проходил и будет проходить незатронутым.

Резюмируя, могу сказать, что это не «вынесение» скриптовой логики. Это разумное разделение управляющих конструкций, по которым ваш пользователь будет обращаться к сайту и конечной логики, которая запрос пользователя будет обрабатывать. При том, при просмотре того же .htaccess становится вполне понятно, почему у юзера вылезла кракозябла при обращении к такому-то URL. Соответственно, программист сотни раз не возвращается к URL-парсеру и не пытается понять, каким шаманским бубном этот параметр привел совершенно в другой модуль.
А как реализовано на wordpresse в url название статьи например?
Имхо, необходимо добавлять правила только для статического контента, все отсальное уже должен делать PHP (ну или другой язык). Гораздо удобнее, когда маршрут определяется только в одном месте.
Т.е. определение маршрута следования за пределами PHP или любого другого скриптового языка средствами предназначенных для этого инструментов вы считаете неправильным?
Если используется фронт-контроллер или его подобие, то да
В чем проблемма использования фронт-контроллера без URL-парсера?
Проблема в том что фронтальный контроллер ограничен набором правил, за пределы которых он никак выйти не сможет, и при добавлении например новой страницы, модуля и т.д. и т.п., или изменения параметров предыдущих — всегда нужно будет возвращаться к изменению набора правил, в случае-же когда фронтальный контроллер имеет все многообразие входящих данных — он просто переадресует их соот-щим контроллерам страниц, наличие которых опять-же определяется в скрипте, и может быть изменено, а может быть вообще нефиксированным.
Как только базовых regexp'ов становится более одного (Вы же рассмотрели самый тривиальный случай), преимущество скриптового языка растет, он ведь имеет множество механизмов управления парсингом (ветвление к примеру). Мод же, как указали выше, будет каждый раз разбирать все последовательно.
mod_rewrite это мощный инструмент для обработки урлов. специально созданный и оптимизированный для этого…
когда вы в скрипте делаете свой обработчик Урлов, вы тратите время на изобретение велосипеда, это факт!
к томуже вы заставляете апач запускать обработчик ПХП при КАЖДОМ запросе, даже когда посетитель пытается запросить ошибочный урл, или даже несуществующий файл…
1. Заведомо ошибочные УРЛы можно отсекать Апачем (хотя их изначально трудно представить пока).
2. Откуда Вы знаете про несуществующий файл, если используются ЧПУ?
3. Ошибки в УРЛе могут быть разными, и я хочу для разных ошибок выдавать различные страницы с ошибками (или передавать в них различный текст, или еще чего) — как быть с апачем?
4. Когда пхп заведомо не нужен (статика к примеру), я не против мода
1) отсекать Апачем? тоесть возвращаемся к необходимости mod_rewrite )))
2) очень просто. Несуществующие УРЛы это те которые не описаны как Валидные среди моих правил! и для которых нет необходимости запускать ПХП и его обработчики вообще…
3) очень просто. вызывайте из Реврайта не статичную 404 страницу, а конкретный модуль обработки ошибок на PHP, ведь это вам никто не запрещает делать.
1. Блин, да никто и не говорит, что он не нужен! НУЖЕН, еще как нужен. Но его одного маловато будет.
2. Сегодня у меня один набор категорий (классов или еще как назовем), завтра я его расширил. Переписывать правила? А ведь у новой категории могут быть свои заморочки…
3. Ответил ниже
2) Нет. мощь реврайта как раз в том, что вы ОДИН раз напишите ОБЩИЕ правила для вашего раздела, и все!
Если предполагается что часть Урла будет динамической, то выделите их в regex-группу и передавайте в скрипт…
а если ОЧЕНЬ СИЛЬНО надо поменять адресацию на сайте, то придется менять Любую карту Урлов хоть на Реврайте хоть в Скрипте )
Да что за за уши притянутые аргументы, для странички Васи Пупкина это конечно все так, а для крупного портала? Вот пытается пользователь запросить ошибочный урл, вы не будете на него писать правил, пусть выдает пустую страницу с 404, пишет в лог апача и хрен с ним? Боюсь что для серьезной разработки это не прокатит, пользователю нужно человеческим языком написать что он набрал неверный адрес, и написать не голой html-страницей, а в оформлении сайта, которое в нормальных системах формируется опять-же скриптами, иже обработчик php в любом случае нужно запускать, нашел-ли он что-то или не нашел, а некоторые системы к тому-же пытаются угадать что конкретно имел ввиду пользователь, и подсказать ему реально существующие варианты.
А что мешает последним правилом все оставшиеся запросы отправить на скрипт обработки ошибок?
А скрипт обработки ошибок-то откуда знает, где именно в УРЛе ошибка? Все равно парсить запрос? Вы ведь это велосипедом назвали…
но тут уже мы свалились в ошибочный запрос… и нам уже пофиг на производительность) и можем перепарсить :)
«к томуже вы заставляете апач запускать обработчик ПХП при КАЖДОМ запросе, даже когда посетитель пытается запросить ошибочный урл» — ну а вот тут человеку жалко производительности :)
Т.е. вместо того, чтобы каждый контроллер управлял своими ошибками в адресации, Вы предлагаете отдельный контроллер ошибок, который должен знать нюансы всех контроллеров, так чтоли?
ну у вас есть выбор… либо дублировать реализацию и получить прирост на типовых запросах, либо все пропускать через скрипт.
Это типичный компромисс между ресурсами разработчика и ресурсами компутера)
Откуда прирост-то? У нас получается ситуация что все верные запросы ведут на скрипт, все неверный также ведут на скрипт, разница лишь в том что URL парсится или предварительно с помощью mod_rewrite, или уже в самом скрипте, то что в скрипте URL будет распарсен медленнее — это очень спорный вопрос.
ок. значит надо решать этот самый спорный вопрос =)
Причем по сути при ошибке УРЛ будет проходить парсинг дважды — сперва в правилах mod_rewrite, затем в скрипте.
с чего вдруг дважды?
раз Реврайт найдет его ошибочным он сразу отдаст его в пхп модуль ошибок.
а что уж там дальше будет происходить уже дело разработчика…
Читайте выше. Просто страница ошибок нас не устраивает.
Ну потому что сначала mod_rewrite распарсит URL, откуда он иначе узнает что он ошибочен, а потом его будет парсить скрипт-обработчик.
1) Реврайт увидел что Урл ошибочный и вызвал error.php?erro_in=news_module
2) error.php выдал умную ошибку специально для раздела News

Где тут двойной парсинг?
)
1. Откуда реврайт узнал, что именно в news_module ошибка? И по какому принципу? И как error.php узнает, в чем именно ошибка этого модуля?
узнает согластно правилу.
как?
читайте доки )

Ой, да ладно…
если вместо /news_module/123/ введут /news_module/abc/ разве реврайт вызовет error.php?erro_in=news_module?

ЗЫ. я использовал реврайт, писал правила, так что не надо меня тыкать в доки, хорошо?
RewriteRule news_module/([^0-9]+) error.php?erro_in=news_module

например так)

хотя я бы так не делал…
Реврайт все таки служит для перенаправления на Валидные урлы а не контроль над всеми возможными Невалидными вариантами…
во-во… отдельное правило… Даже если не ставить цель делать невалидные УРЛы хотя бы более информативными для пользователя, реврайт должен анализировать все возможные варианты построения УРЛа. И по ним ходить (повторюсь, последовательно!) туда-сюда.
А ведь разбор параметров должен делать тот, кто больше об этом знает, и это явно не реврайт
ничто не мешает :) а скрипт обработки ошибок это разве не скрипт? ему интерпритатор не нужен? :) насчет обработки ошибок уже выше написали :)
mod_rewrite занимается разбором Урлов )))
и НИКАК не мешает нам отображать красивые и информативные страницы Ошибок…
с ним все получается очень быстро и гибко)
Тоесть в случае ошибочного адреса mod_rewrite выполнит php-скрипт не запуская php-интерпритатор, и не потратит процессорное время зазря :)
потратит конечно…
но ВЫ же сами этого захотели. чтоб Урл был красивый и умный )))
У нас все должно быть красивым и умным. Если забыли предать последний параметр из N возможных, соответствующий контроллер должен об этом доложить, т.к. он обладает всей информацией, а не страница ошибок.
«к томуже вы заставляете апач запускать обработчик ПХП при КАЖДОМ» — ну так получается заставляем не зря?
зря!
когда все запросы обрабатывает Один скрипт — то даже ошибка в пути до картинки в CSS-файле, будет каждый раз заставлять Апач запускать ПХП ) чтоб показать страницу 404 )

а если разрулить это через Реврвйт то апач сразу скажет что нет такого файла )
а кто сказал, что у нас статика будет рулиться через скрипт? Не будьте таким упорным, мы не требуем НЕ ИСПОЛЬЗОВАТЬ мод :)
а кто сказал что что не будет? ))))
ведь мы щас говорим о конкретных случаях, когда есть только Апач и Пхп и Реврайт…

1) если говорить балансировке нагрузки, о nginx или lighthttpd… то это уже выходит за рамки данного обсуждения. и Опятьже не отменяет преимуществ использования реврайта.

Использование одного скрипта как Фронт-контроллера удобно когда пишется универсальный сайт. чтоб он заработал на большинстве хостингов…
но всем известно что, Универсальное != Оптимальное.
в данном случае более оптимальным и производительным вариантом является использование Реврайта… странно что вы с этим спорите
Вы немного недопоняли, мы не спорим о наличии и отсутствии реврайта — мы спорим о принципах его применения :)
вот именно.
Реврайт заточен для Урл преобразований, а вы мне доказываете что в этом деле — ваш доморощенный скрипт будет быстрее и эффективнее ))

я тоже делал сайты и скриптовым фронт-контроллером и на реврайте и без… и у меня сформировалось свое мнение ))
которое без весомых аргументов вы не измените…
Да пожалуйста, преобразовывайте УРЛы… направляя все на index.php :)
Только когда контроллеры начинают принимать на входе различное количество параметров или разного типа, тут-то mod_rewrite начинает загромождаться
какие параметры?
на входе всегда одна строка — строка Урла, в которой есть все что надо…
реврайт начинает загромождаться НЕ более чем ваша внутрискриптовая карта Урлов… реализацию которой каждый придумывает каждый раз заново и не всегда эффективно и корректно…

а Реврайт он и у Васи пупкина будет быстро и надежно пахать и у Била Гейтса )
site.ru/articles/
site.ru/admin/menus/6/
site.ru/article/add/

И т.д. Писать отдельное правило? А в скрипте будет вызван соответствующий контроллер, который знает, что и в каком количестве должно прийти (и еще по умолчанию может что-то подставить!)
вы просто не знаете как это сделать на Реврайте?
тогда идите читать доки. я цитировать их не буду.

правила для ваших случаев элементарны и написать их можно за пару минут…

если у вас на сайте творится Хаос и Урлы не подчиняются никакой логике то вам и Реврайт не поможет…
Я знаю, как написать для них правила, но это будут разные правила :)
Просто я говорю, что Вы собираете перечень правил реврайта (мы же не говорим об идеальных случаях, когда подойдет одно универсальное правило), т.е. будет уже некий перечень, по которому надо будет пройтись (причем последовательно!)
А index.php на основании первого параметра (имя контроллера) создает этот контроллер и передает обработку ему. Все гибко. Каждый занимается своим делом.
ЗЫ. А к чем Вы постоянно упоминаете термин «внутрискриптовая карта Урлов» я все понять не могу.
«внутрискриптовая карта Урлов» — это так я называю некую абстрактную сущность ) по которой описано соответствие УРЛ=контроллер

а вы что не проверяете даже то что пришло от пользователя а сразу пытаетесь это запустить? ))))
Каждый контроллер сам проверяет, что ему пришло. Зачем все пихать в одно место?
Кстати убедительно. Ведь даже если каждое «правило» внутри скрипта направляет дальнейший ход по одному из двух возможных путей, то самый худший исход для, к примеру, 7 различных вариантов будет 3 последовательно разобранных «правила», а в случае rewrite — 7 «правил». И т.д. По сути можно сравнить бинарное дерево с тупым списком. Сразу становится ясно, что худший исход (максимальное расстояние от корня до любого из элементов) меньше чем в случае списка.
Блин, опять туда же… простые фишки типа статики обрабатываем с помощью mod_rewrite. Там же все остальные случаи направляем на index.php.
При чем тут балансировка, если статика — это стили, картинки, Js и т.д.?
Я-же не отрицаю реврайт как факт :) я отрицаю его использование для формирования пути до каждой отдельной страницы, а ошибку в пути до картинки можно обрезать как раз таки реврайтом, сделав например условие:

RewriteRule \.(gif|png|jpg|jpeg)$ — [L]

перед правилом, передающим управление скрипту.
Я ждал этой строчки ))))
Она еще раз жирно доказывает — что чтобы ваш вариант с Единым скриптом фронт-контроллером, для нормальной работы требует Кучи Костылей, причем опятьже на Реврайте ))

и поверьте, это самый простой и далеко не последний костыль который придется вам прописать…
Каких костылей? Абстрагируясь от реализации — в мод_реврайте два правила, первое — отбросить все что не должно обрабатываться фронтальным контроллером, второе — переадресовать все на фронтальный контроллер.
можно и двумя ) но это моветон и изобретение велосипеда

настоящая мощь реврайта проявляется когда прописаны правила для каждого раздела… если вы этим не пользуетесь то много теряете.
Будете писать 100 правил для 100 разделов? А в конце что-нибудь по дефолту, да?
Вам не кажется, что тут что-то не так? :)
Максимально, мне пришлось прописывать около 30 реврайтов для сайта…
потому что они были не общего вида а достаточно конкретизированные…

в случае с скриптом-парсером нужно былобы писать:
1) парсер Урлов
2) Заполнять такующе карту Урлов
3) в итоге бы это неизвестно как работало…

а с Реврайтом сделал и забыл! пашет и по сей день… и менять там ничего не надо…
Какая еще карта УРЛов? В худшем случае — сверяться с перечнем доступных контроллеров… Необязательно же целиком весь УРЛ анализировать, главное — вычислить, к кому отправить
ну а как вы узнаете какой урл вызывает какой контроллер?
В УРЛе пишется :) Первый параметр — имя контроллера.
Вы не читали, как ЧПУ реализовывается в фреймворках? :)
А сами меня в доки тыкаете
я то как раз знаю. так как написал по их мотивом свой фреймворк )

тоесть. вы тупо пытаетесь запустить контроллер с именем первого пришедшего параметра? даже не проверив есть ли такой контроллер?

наверное нет. вы всеже проверяете, а потом уже запускаете… надеюсь…

а теперь вопрос.
я хочу чтоб контроллер Catalog запускался всегда когда первый параметр= cat или catalog или price или shop.

и вот тут без карты «Урлов никуда». реализовать можно поразному но суть остается тойже…

и вот мне лень писать эту реализацию. потому что Реврайт её мне дает уже готовую
тоесть. вы тупо пытаетесь запустить контроллер с именем первого пришедшего параметра? даже не проверив есть ли такой контроллер?

Проверить параметр на наличие доступного контроллера и пройтись по списку возможных совпадений регэкспом — есть разница, не думаете?
я хочу чтоб контроллер Catalog запускался всегда когда первый параметр= cat или catalog или price или shop. и вот тут без карты «Урлов никуда». реализовать можно поразному но суть остается тойже…

Ну, тут не карта УРЛов, а перечень псевдонимов наверное. Хотя не сказал бы, что такая неоднозначность и разнообразие может кому-то пригодиться :) Может, приведете варианты из жизни?

< Проверить параметр на наличие доступного контроллера
< и пройтись по списку возможных совпадений регэкспом
Реврайт УЖЕ запущен и ищет соответствие в оптимизированной Карте, которая лежит в оперативке

а для вашего случае чтоб проверить одну строку Апач запустит целый отдельный пхп-процесс, на это уйдет время и дополнительная память выделится…

>Может, приведете варианты из жизни?
я вообщето привел. Заказчик хочет чтоб его магазин откликался на разные начальные имена…
или наоборот ситуация. есть урлы типа:
windows/soft/…
linux/soft/…
pda/soft/…
а надо чтоб это все вызывало один контроллер каталого Софта Soft_catalog.
требования бывают очень разные…
Мы уже кажется пришли к тому что php-процесс нам в любом случае запускать :) И дополнительное время и память в любом случае выделится, а уже сравнивать-ли одну строчку жестким соотвествием, или-же парсить десяток-другой регулярок — разница уже будет существенной.
вам привели кучу доводов. а вы продолжаете писать про то что запускать скрипт придется все равно и в Реврайте нет никакого смысла и т.д.…

смысл есть!
я уже устал повторять)

1) Запускать процесс нужно только тогда когда когда сработало — Валидное правило Реврайта. если не сработало значит запросили чтото Невалидное и нет смысла Угадывать чтоже там запросили, потому что сайт не для этого функционирует.
2) Определить Валидный запрос или неВалидный быстрее и проще написав правило в Реврайт, чем писать отдельный парсер запросов…
3) С увеличением кол-ва разных урлов. Реврайт будет по прежнему быстро и стабильно работать. а самописный фронт-контроллер не факт. зависит от скила программера.
4) если вы все еще не видите очевидных плюсов, значит вы просто не хотите их видеть… поэтому не вижу смысла чтото доказывать далее…

сужу по себе. Реврайт меня еще ни разу не подводил. а Свои Урло-парсеры были случаи, но я этот период прошел и сделал для себя правильные выводы…
1. Кто Вам сказал, что «нет смысла» и «сайт не для этого функционирует»? Думаете, интернет-магазину полезнее будет, если при попытке перейти на страницу с несуществующим ноутбуком будет выведена 404? А в скрипте можно вывести список ноутов данной категории или вывести случайный — все на вкус заказчика.
2. Докажите. Тест в статье не показатель, я (и не только я) уже отписал об этом.
3. Увеличение количества разных УРЛов — результат добавления новых контроллеров или методов. С чего вдруг все должно стать нестабильным? А вот в реврайте количество обрабатываемых регэкспов будет расти.
4. Плюсы не так очевидны, как Вам хочется, судя по всему.

Реврайт не подведет, т.к. он железный — что написали «роутить», то и обрабатывает. Но ведь это не оптимальный путь ;)
1. Мы вроде как бы уже определились, что пхп все равно запустится, хотя бы для страницы с ошибкой
2. Даже если это имеет смысл (дойдет ведь до того, что магазин будет открываться по любым введенным буквам и цифрам), можно это обойти, хотя я и считаю, что это очень надуманный пример.
3. Наверное все же логичнее сделать soft/windows, soft/linux и т.д. :)
1 и 2 уже обсудили.
3. нет не логичнее!
сайт весь посвящен софту. и каталог разделяется по платформам…
soft я привел для примера…
там дальше идут уточняющие параметры типа софта… Игры там, или Офисный софт и т.д…
3. Если сайт посвящен софту, какой смысл указывать в УРЛе слово soft? Оно ж тогда лишнее.
вы что издеваетесь?
повторяю
< soft я привел для примера…

перепишу вот так: раз не читаете что я написал
windows/desktop/…
linux/games/…
pda/drivers/…
Ну, вызовется метод platform() контроллера Soft_Controller, ему передастся платформа, далее анализ типа софта в этом методе.
В чем проблема-то?
спасибо что открыли глаза )))

только вот вопрос был в другом…
я же говорю вы не читаете даже о чем я говорю и о чем спросил…
есть урлы типа:
windows/soft/…
linux/soft/…
pda/soft/…
а надо чтоб это все вызывало один контроллер каталого Софта Soft_catalog.

Все это вызовет один и тот же контроллер (да, придется подправить Index.php, но ведь это только один раз делается — как с архитектурой определимся).

А вот то, что для вызова одного и того же контроллера с разным количеством параметров Вам придется писать новые правила, Вы почему-то за минус не считаете. Хотя конечно это железобетонно и надежно :)
согласен. Но вы еще забываете о том что Реврайт помимо простого реврайта Урлов может делать еще очень многое! Такое, что в самописном фронт-контроллере реализация этого будет очень трудна и громоздка…
например:
1) на определенных Урлах — делать редирект
2) отдавать другие заголовки
3) перестраивать или заменять куски Урлов…

это бывает часто нужно при работе сайта. Да, это можно написать и самому, но ЗАЧЕМ?

Я несколько раз тоже пытался написать свой, Гибкий и Мощный Реврайтер в скрипте… И в процессе написания понял что у меня получается двойник mod_rewrite, причем значительно более примитивный…
я понял что теряю время )
1. Если заранее известны определенные условия редиректа (к примеру, на форум или еще что-то выделяющееся), то флаг Вам в руки )) Это полезно, я не спорю.
2. Какие заголовки? Если они общие для сайта, почему бы не сделать это скрипту? Хотя в принципе наверное без разницы…
3. Да, согласен. Но не разбирать УРЛ для клиента.
В общем, реврайт должен подготовить УРЛ, но не разобрать его. Не надо заменять реврайт скриптом, надо максимально сильно использовать их комбинацию.
ну вот )
пришли к консенсусу )
слава богу :) мир дружба жевачка
Итак простейший пример, берем адрес:
/news/detail/10/
Парсер URL разбивает его по слешам, получаем три строки, news, detail, 10, берем первую и используем ее в поиске соот-щего контроллера, инстанциируем, передаем оставшиеся параметры ему. Если не удалось найти соот-щий контроллер — выдается общая ошибка что соот-щий раздел не найден.
Контроллеру новостей приходит два параметра, по первому он определяет действие, если действие отсутствует в списке допустимых — выдает ошибку раздела новостей. Если действие присутствует — передает ему оставшиеся параметры, в нашем случае это десятка, которая используется как идентификатор новости, если нет новости с таким идентификатором — выдается ошибка, что новости с конкретно таким идентификатором не существует.
Где здесь двухсмысленность? Где здесь неоптимальность с точки зрения ресурсов? Происходит только разбивка URL-а по слешу, и последующее сравнение строк один к одному, причем только тех строк, которые впринципе могут у модуля быть. Каждая строка сравнивается единожды.
написал выше.
сразу двоим я писать уже не успеваю
Похоже на красивое решение :)
О каких мощах идёт речь? Что-то мне подсказывает, что смоделировать ситуацию, в которой тупое переписывание маршрутизации из скрипта в .htaccess даст ощутимый прирост в скорости не удасться.
Второй пример явный перебор, вы предлагаете вместо простого intval($var) писать монстровидную регулярку на проверку урла? В чем сакральный смысл этих действий?
Чем она для вас монстровидна? [0-9] конструкция была приведена только для примера. Понимается легче, чем безликие \d.
Я говорил концептуально, а не про данный конкретный случай. И к тому же я говорил об intval в сравнении с регуляркой.
Вы немного неправы. Здесь не факт, что PHPшный intval($var) будет работать быстрее — это раз. Хотя тут, исправьте меня, я могу ошибаться. Второе — будет необходимо городить механизм фильтрации, в котором именно будет присутствовать этот intval() и в соответствии с которым будет определяться, что именно этому $var нужно сделать intval().

В случае «горожения регулярок» нужда в механизме фильтрации для управляющих GET-запросов отпадает.
Гм, чем ваш механизм фильтрации отличается от моего? Я смею утверждать, что фильтровать данные там, где они используются в сотни раз эффективнее, ибо вы пишите хороший код, который самодостаточен, и не полагается на правильность регулярки. Изменение регулярки может порушить значительную часть кода и дать доступ к секретным данным, просто потому что код не перепроверят данные после вашей регулярки. А если перепроверяет, то зачем мне тогда двойная проверка?
Вы зря попытались притянуть за уши какие-то плюсы от использования mod_rewrite по сравнению со скриптом. Я, напимер, уже несколько раз натыкался на универсальный rewrite, который сбрасывает все запросы в index.php, а тот в свою очередь вынимает id страницы из базы по URI. При всей неоднозначности такого подхода в эпоху глобальной раскрутки и СЕО-шники и закзачики пищат от восторга, т.к. могут сами задать любой странице URI, по которому та будет открыта.

А так полезно почитать для общего развития. У меня в закладках болтается пара сайтов. По-моему там довольно доступно написано.
http://www.askapache.com/htaccess/apache-htaccess.html — обо всём понемногу
http://www.htaccesselite.com/mod-rewrite-flags-vt101.html — по большей части о флагах
Т.е. вы этих плюсов не видите?
Универсальные рулесы — зло ^_^ И, снова таки, использование универсальных реврайтов «на все случаи жизни» — скорее от незнания, чем от желания перенести все в одно место и управлять всем из скрипта.
Да нет же. Смотрите выше пример с магазином. Заказчик сам может выбрать, по какому URI откроется та или иная страница. Некоторые за такой бонус готовы душу продать. И всё это делается из админки перописыванием в инпут нужного URI. Можно было бы конечно каждый раз скриптом mod_rewrite генерить, но это уже извращение.
Таким образом разработчик сам себе роет могилу. Точнее не себе, а другим разработчикам, которые прийдут после него и которым заказчик будет говорить «а я вот тут с СЕО общался, а они мне посоветовали, а я сделал — и все сломалось! Поправь пожалуйста, а то все умрем!».

Без нормальной карты перемещений по сайту вы будете долго понимать и разбирать, где в скрипте и что должно куда вести и как, с какими параметрами и т.д. и т.п.

А так заглянул в htaccess, нашел нужный реврайт и смотришь, куда ушло обращение.
Гм. А так заглянул в базу. Это непривычно. Но сделано с умом, так что нестрашно.
Ваш инет магазин работает по принципу?:
1) седня товар доступен по адресу: site.ru/catalog/goods-9786.html
2) на сайт пришли Поисковики и проиндексировали его…
3) завтра вы в админке прописали другое правило… и урлы товаров доступны по адресам типа site.ru/catalog/super_goods-sony_987987.html
4) все посетители пришедшие с поисковиков попадают на страницу 404?

действительно… СЕО-шники пищат )))
В чём надо кого-то ограничивать — тоже вечный спор. Меня, например до сих пор колбасит от Битрикса, в котором тупой заказчик может запросто залезть в любой файл, чего-то поменть, а потом вопить, что ничего не работает. В то же время мне нравятся языки, где понятия private и protected очень условные. Тот же Питон. И Перл в некоторой степени. Как говаривал Лари Уолл, Перл предпочитает чтобы вы не лезли в «приватные» методы и переменные из вежливости, а не потому что у него есть ружьё.

Если вы собираетесь работать с неадекватными людьми то тут вас никакая защита от дурака не спасёт. А так иметь возможность прописать путь к любой странице — это очень неплохо. В принципе даже в случае site.ru/catalog/my-super-goods.html нужно каким-то образом сопоставить «my-super-goods» с id товара. Тут просто пошли дальше и позволяют делать идентификатором всю строку. В некотором роде materialized path.
Если заказчик хочет чтото Неправильное — надо объяснить ему, что он неправ и почему…
в вашем случае, например, Странная «Хотелка» заказчика полностью базовый принцип функционирования Веба, что Урл это идентификатор страницы в сети Интернет, и если он будет всегда меняться то клиент не сможет вернуться к понравившемуся товару, следовательно разочаруется и купит его у ваших конкурентов…
а в итоге Заказчик свалит все на вас и заявит что Вы плохо работаете, так как сайт неэффективен и не приносит прибыли…
сами себе яму роете…
Фигня всё это. Цепочка навигации строится нормально, поисковики индексируют — никаких проблем. Понятное дело, что если попадётся умник, который каждый день будет менять ссылку на страницу, то ничего хорошего не будет. Но добавление какого-нибудь товара с нормальным именем в корень, а не в 33 подкатегории под названием phone-1234 очень часто помогает улучшить позиции в выдаче. Обычно перед празниками замечательно прокатывает.

И, опять-таки, я неоднократно сталкивался с битой ссылкой а-ля /category/phone-1234. Может дамп какой перезалили, может удалили товар изаного добавили… И всё. ID-шники попылли с тем же успехом. От неадеквата ничто не спасёт.
Если кому поможет. Когда будете писать проект с использованием mod_rewrite, не используйте \w \d и др., лучше брать их аналоги [a-z] [0-9]. Это избавит вас от лишних проблем, потому что на некоторых хостингах не поддерживается короткая форма.
при большом желании, вызов парсера url (на любом скриптовом языке) можно запихнуть в map от mod_rewrite. А в последствии вызывать уже конкретный контроллер. На сколько это производительность тянет я не знаю.
Да по-моему ни на сколько не тянет, интерпритатор будет вызываться дважды, один раз чтобы сформировать карту, второй раз чтобы по пришедшим с им-же сформированной карты параметрам вывести страницу.
за то чёткое разграничение между маршрутизатором и контроллерами.
А почему не сделать четкое разделение между маршрутизаторами и контроллерами в пределах одного скрипта? :)
в общем то в этом нет никакой проблемы. дело вкуса.
Сложные условия для реврайта приводят к размазыванию логики приложения. Как правило — это не хорошо.
Все же, считаю, что лучше делать проверку типов в самих скриптах, а не полагаться на Apache и навязывать себе самому зависимость безопасности. Кроме того, в один момент может возникнуть необходимость полностью отказаться от Apache, и перейти на тот же nginx, тогда придется переписывать все правила, где можно что-то потерять при переносе. Ну а в целом rewrite — вещь нужная и полезная.

PS Мой первый комментарий :) Наконец-то зарегистрировался на Хабре. Ура! :)
Плюсанул, с Вас пост :)
Обязательно! Уже даже есть мысль написать про хитрый антиспам для сайта, который однажды пришлось сделать :) Сорри за оффтоп.
Жили были два проекта — у одного было 34 правила в модреврайте
у другого было одно правило и разруливание всего этого дела в пхп…

Один так и работает под апачем, второй работает без апача, напрямую из nginx

Беда и зло mod_rewrite в том что ОГРОМНОЕ количество людей переходя на нгинкс или другой прокси оставляет из-за этого реврайта апач.
Наверное 99% сайтов на фронте которых нгинкс имеют за нгинксом апач…
Ибо родной реврайт нгинкса малек кривоват, точнее сказать он просто другой и для других целей
в чем-то согласен.
Но использовать имеющиеся технологии и возможности надо на всю катушку.
Если щас сайт сидит на Апаче и там есть Реврайт, то какой смысл не использовать этот Реврайт? только потому что когда нибудь, через годик, может быть, сайт переедет на Нгинкс? )))
А вдруг он переедет на LightHttp?
А вдруг он вообще не переедет? )))
Зачем ограничить себя в возможностях?…

Если даже придется переехать, значит есть причины, значит необходима реорганизация структуры сервера, балансировка нагрузки, разделение динамики и статики… тут и без Реврайта очень много проблем и вопросов встанет. И переписать правила под Нгинкс или найти другое решение — это уже решит разработчик в момент когда столкнется с этими проблемами…
и скорее всего он в этом случае вообще уйдет в сторону Java, Django… которые в нагруженных проектах лучше себя показывают…
Sign up to leave a comment.

Articles