Назад | Перейти на главную страницу

Объедините несколько мест с регулярным выражением в nginx

Динамическое количество установок Joomla во вложенных папках домена.

Например:

    http://site/joomla_1/
    http://site/joomla_2/
    http://site/joomla_3/
    ...

В настоящее время у меня есть следующая конфигурация, которая работает:

index index.php;

location / {
    index index.php index.html index.htm;
}

location /joomla_1/ {
    try_files $uri $uri/ /joomla_1/index.php?q=$uri&$args;
}

location /joomla_2/ {
    try_files $uri $uri/ /joomla_2/index.php?q=$uri&$args;
}

location ~ \.php$ {
    fastcgi_pass unix:/var/run/php5-fpm/joomla.sock;
    ...
}

Я пытаюсь объединить правила joomla_N в одно:

location ~ ^/(joomla_[^/]+)/ {
    try_files $uri $uri/ /$1/index.php?q=$uri&$args;
}

но сервер начинает возвращать index.php как есть (не вызывает php-fpm).

Похоже, что nginx останавливает обработку правил регулярных выражений после первого совпадения.

Есть ли способ объединить эти правила с чем-то вроде регулярного выражения?

Давайте разбираться в вещах:

http://wiki.nginx.org/HttpCoreModule#location

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

Итак, сначала перестаньте искать регулярное выражение!

http://wiki.nginx.org/HttpCoreModule#try_files

Проверяет наличие файлов по порядку и возвращает первый найденный файл. Завершающая косая черта указывает на каталог - $ uri /. Если файл не найден, выполняется внутреннее перенаправление на последний параметр. Последний параметр - резервный URI и должен существуют, иначе возникнет внутренняя ошибка.

Итак, последний параметр try_files - это внутренний URL-адрес, по которому повторно вызывается цепочка, если статический файл не найден.

Итак, ответ 1 работает, потому что .php$ regexp сопоставляется только тогда, когда для URL-адреса вызывается внутреннее перенаправление, вместо этого joomla_[^/] всегда соответствует внутреннему URL-адресу php.

Чтобы лучше понять, это также работает в оболочке:

ln -s joomla_1 site_1
ln -s joomla_2 site_2 ...

nginx:

location ~ ^/site_(\d+) {
    try_files $uri $uri/ /joomla_$1/index.php?q=$uri&$args;
}
location ~ \.php$ {
    fastcgi_pass unix:/var/run/php5-fpm/joomla.sock;
    ...
}

URL-адреса пользователей:

http://yoursite.tld/site_1/....

Сначала поместите местоположение .php, а затем поместите это после:

location ~ ^/joomla_(\d+) {
  try_files $uri $uri/ /joomla_$1/index.php?q=$uri&$args;
}