Чпу на mod_rewrite
вступ
Про метод створення ЧПУ (за допомогою mod_rewrite) і пару корисних посилань.
Статтю шановного spectator.ru прокопіпестілі не одну сотню разів. І писати про те які методи є для створення ЧПУ я не буду.
Для цих цілей є спеціальний модуль в Апачі, який називається mod_rewrite. Він дозволяє «перепісививать урли», тобто, перетворювати їх «на льоту» за правилами, які ви йому опишіть.
Досить повну документацію можна подивитися тут. Але вона досить суха і тим хто стикається вперше з модулем mod_rewrite, буде непросто в ній розібратися.
Ще пару корисних посилань і цього буде достатньо:
Чи не працює модуль mod_rewrite? Як перевірити чи підключений модуль?
перевірити, чи встановлений модуль на веб сервері
- Перевірити файл конфігурації Apache (httpd.conf)
- Перевірити роботу сервера з прикладами. Якщо сервер працює без помилок - mod_rewrite встановлений. Якщо немає, отримаєте повідомлення при запиті будь web-сторінки: «Внутрішня помилка сервера»
RewriteEngine on - включає модуль, без нього наступні директиви не враховуватимуться.
Як працює mod_rewrite
Директиви - команди, складова частина мови. Для створення ЧПУ найчастіше використовують дві деріктіви: RewriteCond і RewriteRule.
RewriteCond - умова при якому буде спрацьовувати RewriteRule.
RewriteRule - власне перетворює URL, так само містить в собі умову (шаблон) при якому буде URL «схоплений» і перетворений.
У наступному рядку RewriteCond бере значення змінної% (змінна містить повний шлях в файлової системі сервера до файлу або скрипту, в нашому випадку це просто) і перевіряє умовою! -f ( «!» - ні, «-f» - є звичайним файлом) . Умова спрацювало (немає такого файлу «novaya_statya.html»), йдемо далі.
Умова в RewriteRule (зване «Шаблон» - звикайте) записано у вигляді регульрного вираження «^ ([^ /] *). Html $». Наша рядок проходить перевірку регулярним виразом (регулярний вираз знайшло збіг і зберегло його в змінній $ 1). Всі умови виконані! RewriteRule перенаправить наш запит на /index.php?page= novaya_statya
Ми йшли по коду зверху вниз і все працювало, але насправді все відбувається зовсім не так! Перші пару абзаців в RTFM присвячені саме тому, яким шляхом іде наш модуль, навіть присутні відповідні схеми. Потрібно запам'ятати одну річ: mod_rewrite спочатку заходить в перший RewriteRule, дивиться на збіг з Шаблоном, в шаблон регулярний вираз запам'ятовує в змінні то, що ви захочете, а потім тільки йде в RewriteCond (що відповідає нашому правилом перетворення) і робить перевірку умови. Це так само дає можливість в RewriteCond вести перевірку того, що ви запам'ятали в регулярному виразі, а називається це зворотним зв'язком.
Жорстка структура для ЧПУ
Багато хто робить просто:
А потім в PHP розбирають QUERY_STRING по полицях. Але в цей QUERY_STRING може потрапити все що завгодно і буде необхідно розглянути всі можливі випадки. Так, «всі можливі випадки» - це натяк на регулярні вирази. Я заздалегідь продумав, які ЧПУ будуть зустрічатися на моєму сайті. Так чому б не скористатися регулярними виразами в mod_rewrite і не обмежити логіку движка сайту тільки висновком того, що точно є?
Ви ж чули про «вкладеність» сторінки. Погано якщо користувачеві доводиться п'ять разів клікати, щоб дістатися до «цільової сторінки»? Може коштувати обмежити тоді і ЧПУ, щоб не допустити /categor/subcategory/subsubcategory/subsubsubcategory/article.html. Та це й не ново, що я вам розповідаю ...
Складання регулярних вираженні для mod_rewrite, вилов помилок
Я розбив весь список на дві частини, з «.html» і без них і написав два регулярних вирази (можливо і не варто було так робити, але мені було простіше саме так):
Всі URL які відповідають регулярними виразами - будуть перетворюватися. А з рештою:
Вибачте, помилка 404, сторінка не знайдена.
Отже, для мого випадку:
Все інше, ви вже допишіть самі. Дякуємо за увагу.
Чому даний код не хоче працювати на Apache 1.3, видає помилку. htaccess: RewriteRule: can not compile regular expression '^ (?: ([^ / \.]) [/]?)? (?: ([^ / \.]) [/]?)? $' тобто невірне регулярний вираз. Як його модифікувати що б працювало на apach 1.3?
Спасибі Вам величезне за розумне пояснення! Без дрібної детальки не міг домогтися розширення .php в кінці URL.
to Виталя: Пропустили плюсик після ^ (?: ([^ /.] хоча може у мене в повідомленнях плюсики прибираються перевірка: ^ (?: ([^ /.]) [/]?)? (?: ([^ / .]) [/]?)? $