LINUX.ORG.RU

Apache rewrite rule => Nginx rewrite rule


0

0

Помогите пожалуйста с переносом следующего правила на Nginx;

RewriteEngine On
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^([^/.]+)/?(.*)$ /$1.php/$2 [QSA,L]
RewriteRule ^api/([a-z]+)/([a-z]+) /api/$1_$2.php

Сам не могу распарсить. Написал пока такое, но не все работает -

if (-f $request_filename.php) { rewrite ^/([^/.]+)/?(.*)$ /$1.php?query=$2 last; }


if ( -f $request_filename.php) {
    rewrite ^([^/.]+)/?(.*)$ /$1.php/$2 last;
    rewrite api/([a-z]+)/([a-z]+) /api/$1_$2.php last;
}

Предполагается, что все это внутри location / {}.

sjinks ★★★
()
Ответ на: комментарий от jj1111

И? Что не работает? Если можно, с конкретными примерами.

ЗЫ: у меня правила от Ваших отличаются, если что.

sjinks ★★★
()
Ответ на: комментарий от jj1111

Ну тогда проблема в условии if ( -f $request_filename.php ). Оно проверяет именно существование файла.

Набор файлов из первой части условия (([^/.]+)) ограничен?

sjinks ★★★
()
Ответ на: комментарий от sjinks

Можно просто сделать

location ~ /(tags|...|...) {
    rewrite ^/(tags|...|...)(/.*)?$ $1.php$2 break;
}
sjinks ★★★
()
Ответ на: комментарий от jj1111

Извращение :-(

[code] location / { set $file ""; set $exists ""; if ( $request_filename ~ ^(/[^/.]+)(/.*)?$ ) { set $file $1; }

if ( $file = «» ) { # что-то делаем }

if ( -e $file ) { rewrite ^(/[^/.]+)(/.*)?$ /$1.php$2 last; } } [/code]

Честно скажу, что не проверял, но идея такая.

sjinks ★★★
()
Ответ на: комментарий от jj1111
error_page 404 = @myhandler;
log_not_found off;

location @myhandler {
    fastcgi_pass ...;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    include /etc/nginx/fastcgi_params;
    fastcgi_param SCRIPT_NAME /index.php;
}

location ~ \.php$ {
    try_files $uri @myhandler;

    fastcgi_index index.php;
    fastcgi_pass ...;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include /etc/nginx/fastcgi_params;
}

index.php анализирует $_SERVER['REQUEST_URI'] и принимает решения о пути выполнения программы. В результате имеем простую логику в конфиге и отсутствие необходимости перебирать кучу правил/проверок на существование при каждом запросе.

Понимаю, что скрипт менять, вероятно, поздно, но это рекомендуемая практика. А использование всяких if ( -f ... ) плохо в любом случае.

sjinks ★★★
()
Ответ на: комментарий от true_admin

try_files в случае ТС не поможет: ему нужно выполнить переписывание урла в случае, если файл существует.

try_files $request_filename.php ...; просто бы передал управление этому файлу.

sjinks ★★★
()
Ответ на: комментарий от true_admin

Не совсем.

Например, try_files $uri $uri/ @something; сначала ищет файл $uri, если не нашел, то каталог $uri/, если же нет и каталога, то отдаёт управление именованному location.

Т.е. в случае try_files rewrite внутри location будет выполнен, если файл/каталог $uri НЕ существует. ТС нужно наоборот: если файл существует, то выполнить rewrite.

sjinks ★★★
()
Ответ на: комментарий от sjinks

Ты же указал правильный конфиг в Apache rewrite rule => Nginx rewrite rule (комментарий) , о чём сейчас споришь? try_files лишь позволяет перекидывать в fallback-локейшн если файла нет, а если есть try_files работает так как буд-то и нет этой директивы.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

А, вот в чем дело :-) Я просто думал, что речь идет об оригинальном сообщении ТС, а не о предложенном мной конфиге.

Да, тогда можно и try_files.

Причина, по которой я предпочитаю error_page на верхнем уровне, такова: если у нас есть несколько разных location, для которых 404 ошибку должен обрабатывать один и тот же скрипт — как в Апаче

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

то try_files придется повторять во всех location, ибо он не наследуется.

То есть

try_files $uri $uri/ @wordpress;

location ^~ /wp-content/uploads/ {
    location ~ \.(css|js|gif|png|jpg|flv|swf|htm|html|zip|gz|xml|JPG|bz2|txt|ico|avi|mpe?g|mp[34])$ {
        expires 30d;
        try_files $uri $uri/ @wordpress;
    }

    location ~ \.php$ {
        types {
            text/plain php;
        }
    }
}

location @wordpress {
    fastcgi_pass unix:/dev/shm/php-fcgi.sock;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    include /etc/nginx/fastcgi_params;
    fastcgi_param SCRIPT_NAME /index.php;
}

location ~ \.php$ {
    try_files $uri @wordpress;
    fastcgi_index index.php;
    fastcgi_pass unix:/dev/shm/php-fcgi.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include /etc/nginx/fastcgi_params;
}

Без этого nginx прочто будет возвращать свою дефолтную 404 страницу.

А так проще (особенно, если много location):

error_page 404 = @wordpress;
log_not_found off;

try_files $uri $uri/ @wordpress;

location ^~ /wp-content/uploads/ {
    location ~ \.(css|js|gif|png|jpg|flv|swf|htm|html|zip|gz|xml|JPG|bz2|txt|ico|avi|mpe?g|mp[34])$ {
        expires 30d;
        try_files $uri $uri/ @wordpress;
    }

    location ~ \.php$ {
        types {
            text/plain php;
        }
    }
}

location @wordpress {
    fastcgi_pass unix:/dev/shm/php-fcgi.sock;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    include /etc/nginx/fastcgi_params;
    fastcgi_param SCRIPT_NAME /index.php;
}

location ~ \.php$ {
    try_files $uri @wordpress;
    fastcgi_index index.php;
    fastcgi_pass unix:/dev/shm/php-fcgi.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include /etc/nginx/fastcgi_params;
}

Так как error_page наследуется, то конфиг получается короче.

sjinks ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.