php - 如何使用 nginx 和 php 进行没有 .php 扩展名的路由

标签 php docker nginx url-rewriting

在开始之前,我知道 StackOverflow 中有很多关于此问题的解决方案,但它们不适用于我的情况。

我使用 PHP 设置了一个运行 Nginx 实例的 docker 容器。当我输入这样的 URL myapp.com/somefile 末尾没有 .php 时,它找不到该文件。我需要浏览此 URL 才能使其正常工作 myapp.com/somefile.php。

这是我的 Dockerfile 和 Nginx 配置。

Dockerfile

FROM php:7.4.8-fpm

RUN apt-get update -y \
    && apt-get install -y nginx

# PHP_CPPFLAGS are used by the docker-php-ext-* scripts
ENV PHP_CPPFLAGS="$PHP_CPPFLAGS -std=c++11"

RUN docker-php-ext-install pdo_mysql \
    && docker-php-ext-install opcache \
    && apt-get install libicu-dev -y \
    && docker-php-ext-configure intl \
    && docker-php-ext-install intl \
    && apt-get remove libicu-dev icu-devtools -y
RUN { \
        echo 'opcache.memory_consumption=128'; \
        echo 'opcache.interned_strings_buffer=8'; \
        echo 'opcache.max_accelerated_files=4000'; \
        echo 'opcache.revalidate_freq=2'; \
        echo 'opcache.fast_shutdown=1'; \
        echo 'opcache.enable_cli=1'; \
    } > /usr/local/etc/php/conf.d/php-opocache-cfg.ini

COPY nginx-site.conf /etc/nginx/sites-enabled/default
COPY entrypoint.sh /etc/entrypoint.sh

COPY --chown=www-data:www-data . /var/www/html

WORKDIR /var/www/html

EXPOSE 80 443

ENTRYPOINT ["sh", "/etc/entrypoint.sh"]

nginx-site.conf

server {
    root    /var/www/html;

    include /etc/nginx/default.d/*.conf;

    index index.php index.html index.htm;

    client_max_body_size 30m;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        # Mitigate https://httpoxy.org/ vulnerabilities
        fastcgi_param HTTP_PROXY "";
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        include fastcgi.conf;
    }
}

如何解决这个问题?任何帮助将不胜感激!

注意:我尝试将这行代码添加到 nginx 配置中,但最终我下载了文件而不是执行它们:

location / {
    try_files $uri $uri.html $uri/ @extensionless-php;
    index index.html index.htm index.php;
}

location ~ \.php$ {
    try_files $uri =404;
}

location @extensionless-php {
    rewrite ^(.*)$ $1.php last;
}

最佳答案

是的,您不能强制 nginx 通过 PHP location 处理程序使用 try_files $uri $uri.php ... 之类的内容强制提供 PHP 脚本。您可以尝试使用此配置(是的,我知道某些 if block 是邪恶的,但不用担心,这个不是):

location / {
    index index.html index.htm index.php;
    try_files $uri $uri.html $uri/ @extensionless-php;
}

location ~ \.php$ {
    # default PHP handler here
    ...
}

location @extensionless-php {
    if ( -f $document_root$uri.php ) {
        rewrite ^ $uri.php last;
    }
    return 404;
}

如果您想将所有未找到的请求重定向到 index.php,请改用这个:

location @extensionless-php {
    if ( -f $document_root$uri.php ) {
        rewrite ^ $uri.php last;
    }
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME $document_root/index.php;
    include fastcgi.conf;
}

关于php - 如何使用 nginx 和 php 进行没有 .php 扩展名的路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62979718/

相关文章:

php - 如何在Mysql中创建一个id(自动递增)并与其连接一个字符串?仅使用 PHP

Jenkins:在构建图像时将(环境)变量传递给 Docker

linux - 用于端口路由的 docker ha 代理

docker - 无法连接到转发任何端口的 docker 端口

javascript - SailsJS - 创建版本化 API,无需蓝图

Nginx 虚拟主机不工作(错误的重定向)

php - 全局创建者,任何插入查询的时间跨度

php - 使用 codeigniter Controller 中的++ 增加 mysql 值

javascript - 使用 Javascript 和 PHP 将 JSON 存储为 CSV

Docker 数据卷容器。我似乎无法备份