Блог ищущего программиста

Регулярные выражения

Наконец-то разобрался с регулярными выражениями. Решил красиво сделать реврайты к сайтам. На локальной машине у меня Apache, а на хостинге — nginx. Поэтому пришлось постигать различия в написании конфигов. Apache намного привередливее. Постоянно где-то что-то не так. Например, флаг [L] странно работает. Нужно ставить дополнительные проверки, иначе вылезает ошибка:
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use ‘LimitInternalRecursion’ to increase the limit if necessary. Use ‘LogLevel debug’ to get a backtrace
Вот пример моего апачевского .htaccess:

AddDefaultCharset UTF-8
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
 
RewriteRule ^groups/([^/]+)$ /index.php?g=$1&action=week [L]
RewriteRule ^groups/([^/]+)/(201[1-9]-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]))$ /index.php?g=$1&action=week&d=$2 [L]
RewriteRule ^groups/([^/]+)/([^/]+)/(201[1-9]-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]))$ /index.php?g=$1&action=$2&d=$3 [L]
RewriteRule ^groups/([^/]+)/([^/]+)$ /index.php?g=$1&action=$2 [L]
 
RewriteRule ^([^(/.)]+)$ /index.php?action=$1 [L]
RewriteRule ^([^/]+)/([^(/.)]+)$ /index.php?action=$1&p1=$2 [L]
RewriteRule ^([^/]+)/([^(/.)]+)/([^/]+)$ /index.php?action=$1&p1=$2&p2=$3 [L]
 
RewriteRule ^$ /index.php?action=root [L]

Если не указать в выражении ^(/.) помимо слэша точку, то вылетает вышеуказанная ошибка. Происходит это из-за того, что как я понял, не срабатывает [L] — окончание обработки адреса. А так, получившийся index.php нормально попадает под второе выражение. И каким-то образом получается цикл. Поиск не помог, пришлось выходить из ситуации так. Конечно можно было пойти более простым путем, и проверку на дату вывести в php. Да и вообще весь парсинг вывести в код, а реврайт сделать один глобальный, но захотелось разобраться.

Теперь про отличия реврайтов nginx и Apache:

  1. В nginx нужно заменить [L] на last;
  2. В nginx начало строки  rewrite ^/ вместо  RewriteRule ^ . точнее в nginx нужен корневой слеш : rewrite ^/([^/]+)$ /index.php?action=$1 last; , а в Apache, наоборот

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

Конечно же, все, наверное, проще. Если кто напишет правильный вариант конфига для Apache, буду признателен.

Пример того же конфига nginx:

location / {
root /home/site;
index index.php index.html index.htm;
 
if (!-f $request_filename ) {
 
rewrite ^/$ /index.php?action=root last;
rewrite ^/groups/([^/]+)$ /index.php?g=$1&action=week last;
rewrite ^/groups/([^/]+)/(201[1-9]-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]))$ /index.php?g=$1&action=week&d=$2 last;
rewrite ^/groups/([^/]+)/([^/]+)/(201[1-9]-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1]))$ /index.php?g=$1&action=$2&d=$3 last;
rewrite ^/groups/([^/]+)/([^/]+)$ /index.php?g=$1&action=$2 last;
 
rewrite ^/([^/]+)/([^/]+)_([^/]+)/$ /index.php?action=$1&p1=$2&p2=$3 last;
 
rewrite ^/([^/]+)$ /index.php?action=$1 last;
rewrite ^/([^/]+)/([^/]+)$ /index.php?action=$1&p1=$2 last;
 
rewrite ^/([^/]+)/$ /$1 permanent;
rewrite ^/([^/]+)/([^/]+)/$ /$1/$2 permanent;
rewrite ^/([^/]+)/([^/]+)/([^/]+)/$ /$1/$2/$3 permanent;
rewrite ^/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ /$1/$2/$3/$4 permanent;
 
}
 
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php;
}
}

На самом деле я сначала писал конфиг под nginx, а затем воевал с Apache. Но здесь почему-то получилось написать наоборот.

UPD: онлайн-конвертер .htaccess в правила nginx есть тут, но пишут, что бывают глюки.

 

 

Опубликовал 30th Сентябрь 2011.
Размещено в Web.
Метки: , .

Ранее в этой же рубрике:


Комментирование закрыто.

35 - здесь у нас SQL запросов.
0,119666 - время на генерацию страницы.