Если я правильно понимаю, как работает эта система, давайте попробуем для начала два следующих файла:
/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
location / {
try_files $uri $uri/ @extensionless-php;
}
location @extensionless-php {
rewrite ^ $uri.php last;
}
/opt/docker/etc/nginx/vhost.common.d/10-php.conf
location ~ \.php$ {
try_files $uri /<DOCUMENT_INDEX>?_url=$uri&$args;
fastcgi_pass php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_read_timeout <PHP_TIMEOUT>;
}
Вышеупомянутая конфигурация имеет один серьезный недостаток. Если запрошенный URI не является именем существующего файла PHP (с расширением .php
или без него), значение внутренней переменной $uri
nginx всегда будет заканчиваться на .php
из-за правила rewrite
внутри именованного местоположения @extensionless-php
. Это приведет к следующему (при условии, что файл /app/public/some/path.php
не существует):
/some/path
=> /index.php?_url=/some/path.php
/some/path.php
=> /index.php?_url=/some/path.php
Чтобы решить эту проблему, мы можем сохранить исходное значение переменной $uri
внутри именованного местоположения extensionless-php
:
/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
location / {
try_files $uri $uri/ @extensionless-php;
}
location @extensionless-php {
set $original_uri $uri;
rewrite ^ $uri.php last;
}
/opt/docker/etc/nginx/vhost.common.d/10-php.conf
location ~ \.php$ {
try_files $uri /<DOCUMENT_INDEX>?_url=$original_uri&$args;
fastcgi_pass php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_read_timeout <PHP_TIMEOUT>;
}
Эта конфигурация лучше, но все же имеет недостаток. Если запрошенный URI заканчивается на .php
и в каталоге /app/public
нет соответствующего PHP-файла, переменная $original_uri
не будет инициализирована, а аргумент запроса _url
будет передан бэкенду в виде пустой строки:
/some/path
=> /index.php?_url=/some/path
/some/path.php
=> /index.php?_url=
Это может быть нормально для некоторых веб-приложений (пустой аргумент запроса _url
всегда означает недопустимый маршрут), но что нам делать, если мы хотим получить исходный URI, каким бы он ни был? Мы можем добиться этого с помощью директивы map
( чрезвычайно мощная функция nginx). Однако все блоки map
должны быть объявлены вне блоков server
, поэтому нам понадобится дополнительный файл:
/opt/docker/etc/nginx/conf.d/10-map.conf
map $_uri $original_uri {
"" $uri;
default $_uri;
}
/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
location / {
try_files $uri $uri/ @extensionless-php;
}
location @extensionless-php {
set $_uri $uri;
rewrite ^ $uri.php last;
}
/opt/docker/etc/nginx/vhost.common.d/10-php.conf
location ~ \.php$ {
try_files $uri /<DOCUMENT_INDEX>?_url=$original_uri&$args;
fastcgi_pass php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_read_timeout <PHP_TIMEOUT>;
}
Этот блок map
означает, что переменная $original_uri
была бы равна $uri
единице, если бы она не была изменена (переменная $_uri
не инициализирована и пуста). Если переменная $_uri
не пуста, это означает, что исходная переменная $uri
была изменена, а переменная $_uri
теперь сохраняет свое исходное значение, поэтому значение переменной $original_uri
будет установлено на $_uri
. Эта конфигурация должна работать с любыми запросами, сохраняющими исходный URI в качестве аргумента запроса _url
.
person
Ivan Shatsky
schedule
20.10.2020
location ~ \.php$ { ... }
)? - person Ivan Shatsky   schedule 19.10.2020/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
, а неopt/docker/etc/nginx/conf.d/10-location-root.conf
. Я думаю, что ваши модификации вообще не работают. - person Ivan Shatsky   schedule 20.10.2020server
вы вообще не сможете выполнить какой-либо PHP-скрипт, а еслиabc.php
работает как положено, значит, его обрабатывает какой-то другой конфиг (думаю, дефолтный). Мне кажется, что вам нужно изменить как минимум два файла -/opt/docker/etc/nginx/vhost.common.d/10-location-root.conf
и/opt/docker/etc/nginx/vhost.common.d/10-php.conf
, возможно, добавить третий пользовательский файл в/opt/docker/etc/nginx/conf.d/
, скажем,/opt/docker/etc/nginx/conf.d/maps.conf
. - person Ivan Shatsky   schedule 20.10.2020/opt/docker/etc/nginx/conf.d/10-location-root.conf
, поставьте вместо него эти два файла и проверьте, как он работает. Оставьте свой/app/public
контент как есть. - person Ivan Shatsky   schedule 20.10.2020