За последние 24 часа нас посетил 21381 программист и 1699 роботов. Сейчас ищет 1791 программист ...

mod_rewrite RewriteCond не находит существующие файлы

Тема в разделе "Регулярные выражения", создана пользователем Yadfewm, 28 ноя 2013.

  1. Yadfewm

    Yadfewm Активный пользователь

    С нами с:
    20 июл 2009
    Сообщения:
    223
    Симпатии:
    0
    С разделом, возможно, ошибся, сори.

    Код ведёт себя странно и не видит файлы которые существуют.
    Код (Text):
    1.  
    2. ...
    3. RewriteCond %{REQUEST_FILENAME} !-f
    4. ...
    5. RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)\.html$ index.php?category=$1&section=$2&element=$3&ha=%{REQUEST_FILENAME} [L]
    6. ...
    Вкратце теорию:

    RewriteCond - Определяет условие при котором происходит преобразование, условие следущее: %{REQUEST_FILENAME} - запрашиваемый файл, !-f - не является файлом (не существует)

    Далее само преобразование запроса ( строки вида abcdefgh/abcdefgh/abcdefgh.html если файла не существует то перенаправляем на index.php с параметрами.., например:
    /news/business/newbiz-for-you.html
    --->>>
    index.php?category=news&section=business&item=newbiz-for-you
    )

    Итак преобразование должно осуществляться только тогда, когда файла не существует.

    Тут мне взбрело в голову посмотреть, как выглядит шаблон сайта в браузере (theme/tpls/main.html). Он реально есть по этому пути, я его собственно запрашиваю, но срабатывает преобразование!!! И кноечно меня кидает на 404 страницу.

    Сейчас углубляюсь где же может быть косяк, вроде всё просто до безумия, но не работает как хочется.

    код htaccess

    Код (Text):
    1. # Включаем модуль mod_rewrite выполняющий URL преобразования на лету
    2. RewriteEngine on
    3. # Устанавливает базовый URL для преобразований в каталоге
    4. RewriteBase /
    5.  
    6.  
    7. # Перенаправление с адреса без www на адрес с www. R[=code] - вызывает редирект. L - чтобы не преобразовывать текущий URL другими правилами преобразований. QSA - добавлять строку запроса
    8. # Перенаправление с явным указанием переменной
    9. RewriteCond %{HTTP_HOST} !^www\. [NC]
    10. RewriteCond %{HTTP_HOST} !^$
    11. RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]
    12.  
    13. # Перенаправление вручную
    14. #RewriteCond %{HTTP_HOST} ^domen.ru [NC]
    15. #RewriteCond %{HTTP_HOST} !^$
    16. #RewriteRule ^(.*)$ http://www.domen.ru/$1 [R=301,L]
    17.  
    18. # Перенаправление с адреса с www на адрес без www
    19. ##RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
    20. ##RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
    21.  
    22.  
    23.  
    24.  
    25.  
    26.  
    27.  
    28.  
    29.  
    30.  
    31. # Админка
    32. RewriteCond %{REQUEST_FILENAME} !-d
    33. RewriteRule ^admin/([^/\.]+)/?$ /admin/index.php?category=$1 [L,QSA]
    34.  
    35.  
    36. # Сайт
    37. RewriteCond %{REQUEST_FILENAME} !-d
    38. RewriteRule ^([^/\.]+)/?$ index.php?category=$1 [L]
    39. RewriteRule ^([^/\.]+)/([0-9]+)/?$ index.php?category=$1&page=$2 [L]
    40. RewriteRule ^([^/\.]+)/([^/\.]+)/?$ index.php?category=$1&section=$2 [L]
    41. RewriteRule ^([^/\.]+)/([^/\.]+)/([0-9]+)/?$ index.php?category=$1&section=$2&page=$3 [L]
    42.  
    43.  
    44. RewriteCond %{REQUEST_FILENAME} !-f
    45. RewriteRule ^([^/\.]+)/([^/\.]+)\.html$ index.php?category=$1&element=$2 [L]
    46. RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)\.html$ index.php?category=$1&section=$2&element=$3&ha=%{REQUEST_FILENAME} [L]
    47.  
    48.  
    49. RewriteCond %{REQUEST_FILENAME} !-d
    50. RewriteCond %{REQUEST_FILENAME} !-f
    51. RewriteRule ^.*$ 404/
    52.  
    53.  
    54. # Шпаргалка
    55. # RewriteCond
    56. # [flags]:
    57. # 'nocase|NC' - регистронезависимо
    58. # 'ornext|OR' - либо следующее условие
    59. # '-d' является ли каталогом
    60. # '-f' является ли обычным файлом
    61. # '-s' является ли обычным файлом с ненулевым размером
    62. # '-l' является ли символической ссылкой
    63. # '-F' проверка существования файла через подзапрос
    64. # '-U' проверка существования URL через подзапрос
    Добавлено спустя 17 минут 16 секунд:
    Блин, нашел где копать, работает как хочу если так:
    Код (Text):
    1. RewriteCond %{REQUEST_FILENAME} !-f
    2. RewriteRule ^([^/\.]+)/([^/\.]+)\.html$ index.php?category=$1&element=$2 [L]
    3. RewriteCond %{REQUEST_FILENAME} !-f
    4. RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)\.html$ index.php?category=$1&section=$2&element=$3&ha=%{REQUEST_FILENAME} [L]
    Я то думал что RewriteCond объединяющее условие для всех последующих RewriteRule. Может [L] тому причина

    Добавлено спустя 7 минут 49 секунд:
    Нихрина себе ошибочка, как у меня вообще всё работает %) ???
     
  2. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    чувак, а не п роще ли RewriteRule ^.*\.html$ index.php
    =)
    а в индексе просто добавь воды implode('/', $_SERVER['REQUEST_URI'])
     
  3. Yadfewm

    Yadfewm Активный пользователь

    С нами с:
    20 июл 2009
    Сообщения:
    223
    Симпатии:
    0
    ты не первый кто мне это советует) и я параллельно пишу ещё один собственный движок с разбором запроса в php

    а тут вся прелесть в том, что у меня в индексе нет воды =)

    теоретически можно углубиться в воду очень глубоко, а если сайт простенький то этого не надо

    мне кажется тут дело вкуса..: с помощью этого прекрасного модуля я могу описать всю структуру ЧПУ сайта очень наглядно (я считаю этот код довольно наглядным:
    Код (Text):
    1. RewriteCond %{REQUEST_FILENAME} !-d
    2. RewriteRule ^([^/\.]+)/?$ index.php?category=$1 [L]
    3. RewriteRule ^([^/\.]+)/([0-9]+)/?$ index.php?category=$1&page=$2 [L]
    4. RewriteRule ^([^/\.]+)/([^/\.]+)/?$ index.php?category=$1&section=$2 [L]
    5. RewriteRule ^([^/\.]+)/([^/\.]+)/([0-9]+)/?$ index.php?category=$1&section=$2&page=$3 [L]
    6.  
    7.  
    8. RewriteCond %{REQUEST_FILENAME} !-f
    9. RewriteRule ^([^/\.]+)/([^/\.]+)\.html$ index.php?category=$1&element=$2 [L]
    10. RewriteRule ^([^/\.]+)/([^/\.]+)/([^/\.]+)\.html$ index.php?category=$1&section=$2&element=$3 [L]
    )

    в идеале если запрос не соответствует структуре, то посылается на *** 404.php, срочно, без implode и попадания в index.php ...

    Добавлено спустя 7 минут 28 секунд:
    Неужто кроме меня этот модуль никто не изучает? =( очень мало ответов когда я пишу вопросы связанные с модреврайт

    Ещё один минибаг: в документации можно так:
    Код (Text):
    1. RewriteCond ... ... [OR]
    2. RewriteCond ... ...  [OR]
    3. RewriteCond ... ...
    4. RewriteRule ...some special stuff for any of these hosts...
    А на моём сервере, если вставить [OR] апач уходит в 500 (((
     
  4. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    от сердца отрываю
    Код (PHP):
    1. <?php
    2.  
    3. class URI {
    4.  
    5.   public static
    6.           $url = '',
    7.           $section = false,
    8.           $entry = false,
    9.           $action = false,
    10.           $param = false,
    11.           $shifted = false;
    12.   private static
    13.           $shift = 1;
    14.  
    15.   public static function Init() {
    16.     $url = parse_url($_SERVER['REQUEST_URI']);
    17.     self::$url = $url['path'];
    18.     $url['path'] = trim($url['path'], '/');
    19.     $s = explode('/', $url['path'], self::$shift);
    20.     $path = explode('/', array_pop($s), 5);
    21.     self::$shifted = $s;
    22.     if (is_array($path)) {
    23.       if (isset($path[0]) AND $path[0] !== '')
    24.         self::$section = strtolower($path[0]);
    25.       if (isset($path[1]) AND $path[1] !== '')
    26.         self::$entry = strtolower($path[1]);
    27.       if (isset($path[2]) AND $path[2] !== '')
    28.         self::$action = strtolower($path[2]);
    29.       if (isset($path[3]) AND $path[3] !== '')
    30.         self::$param = strtolower($path[3]);
    31.     }
    32.   }
    33.  
    34.   public static function Shift() {
    35.     self::$shift++;
    36.     self::Init();
    37.   }
    38.  
    39. }
    40.  
    41. URI::Init(); 
     
  5. Yadfewm

    Yadfewm Активный пользователь

    С нами с:
    20 июл 2009
    Сообщения:
    223
    Симпатии:
    0
    а можно пояснение структуры чпу?
    секция(section) - страница сайта - допустим, понятно.
    entry, action, param - как это едят, что это?

    И интересно ваше мнение на мою "самоделкину" структуру сайтостроения:

    catgory/section/item.html

    catgory - страницы сайта.
    например: /mypage/ или /contacts/ или /news/
    могут содержать текст - статические, но могут содержать спец тэг ??news??, тогда подключается модуль новостей и в страницу сбрасывает нужный от ситуации контент, например постраничный вывод новостей: /news/1/, /news/2/ ... или сама новость: /news/first-news.html (надеюсь понятно)

    section - понятное дело, новостей много, хотим группировать, получаем возможные варианты:

    catgory/
    catgory/page/
    catgory/section/
    catgory/section/page/

    catgory/item.html
    или
    catgory/section/item.html

    а вот
    для меня пока загадка. Видимо позаимствовано из какого нибудь хорошего продуманного движка c фильдеперсовой MVC схемой? =)

    Добавлено спустя 3 минуты 23 секунды:
    как видите, в моей схеме ЧПУ на втором месте (после /catgory/) у меня может быть как /page/ так и /section/ и регуляркой хорошо определяется что имеется в виду
     
  6. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    /section/entry/action/всё остальное
    /news/7/edit как пример

    можешь назвать как хочешь свои сам. суть проста - потрошить реквест ури извнутре пхп и не парить себе голову. потрошить без регулярок простым имплодом.
     
  7. Yadfewm

    Yadfewm Активный пользователь

    С нами с:
    20 июл 2009
    Сообщения:
    223
    Симпатии:
    0
    в малых проектах нехочу, так как мои 8 строк регулярных не считаю за
    мне гораздо сложнее прочитать 8 if в пхп коде.

    После моих регулярок мне остается описать сам алгоритм используя примерно такое:
    Код (Text):
    1. if isset($_GET['section'])
    2. тармам пам пам
    3. else
    4. турум пум пум
    в общем спасибо за класс, в новом своём движке переношу логику в пхп, там для SEO внедрятся такая штука:
    /турум/пум/пум/тарам/пам/пам/бац/
    /турум/пум/пум/ - определяет выводимую страницу, несмотря на то, что нужен лишь последний /пум/ (являющийся строковым ID выводимой страницы) в ЧПУ отображается весь путь (древовидная структура страниц сайта) до нужной страницы.
     
  8. Your

    Your Старожил

    С нами с:
    2 июл 2011
    Сообщения:
    4.074
    Симпатии:
    7
    Но зачем делать Cond если ты опять делаешь запрос на файл?!
    ha=%{REQUEST_FILENAME}
    Похоже в этом проблема.
    ha=%1 или какой там, по счету вызов файла.

    Мой, вам совет! Чем больше вложенность /././././, тем хуже роботу.
     
  9. Yadfewm

    Yadfewm Активный пользователь

    С нами с:
    20 июл 2009
    Сообщения:
    223
    Симпатии:
    0
    чисто для проверки, в рабочей версии нет

    абсолютно вы правы, просто эксперимент провел в своём случае

    согласен, но если контента дожопы и он действительно по смыслу имеет древовидную структуру, то почему бы не реализовать её в ЧПУ, особенно, когда кроме таких страниц /././././, существуют и такие /./././ и такие /././ (тоесть действительно объединяющие (корневые) страницы - существуют)

    Добавлено спустя 1 минуту 17 секунд:
    ну 5-6 вложений я думаю сожрет не поперхнется