ThinkPHP 的 nginx 配置踩坑

THINKPHP 的 NGINX 配置踩坑

今天在用一个以 tp 为基础的快速开发框架时遇到一些问题:

nginx 报错截图

thinkphp 的 nginx 配置踩坑
为了方便说明进行手动换行

// 处理时重写或内部重定向循环
2019/11/11 11:16:06 [error] 15164#15432: *1 rewrite or internal redirection cycle while processing 
    "/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index/user/index.html", 
    client: 127.0.0.1, 
    server: xxxxx, 
    request: "GET /index/user/index.html HTTP/1.1", 
    host: "xxxxx", 
    referrer: "xxxxx"

错误配置

参考 larvael 配置

server {
    .
    .
    .

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    .
    .
    .
    location ~ \.php$ {
        fastcgi_pass127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
    }
    .
    .
    .

}

发现所有路径都一样,都是首页效果

初步判断 nginx 重写规则有问题

# 路径 / 开头之后都走这个匹配
# 如 /index /index/user 
location / {
    # $uri 本地有就返回,或者$uri/ 本地有目录就返回,或者走后面的重写
    # 本地是指在网站根目录下,如 当 $uri=index 就是看根目录下面有 index 文件或者 index/ 目录
    try_files $uri $uri/ /index.php?$query_string;
}

开始报错

解决问题

网上查询后 tp5 的配置应为

    location / {
        try_files $uri $uri/ /index.php$uri?$query_string;
    }

改后,发现问题没解决;对比配置发现

    # location ~ \.php$ 改成  location ~ \.php(.*)$
    location ~ \.php(.*)$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO  $fastcgi_path_info;
        fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;
        include fastcgi_params;
    }

解决,完整配置

server {
    listen       80;
    server_name  xxxxxxx ;
    root  www;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Content-Type-Options "nosniff";

    charset utf-8;

    index index.html index.htm index.php;
    location / {
        try_files $uri $uri/ /index.php$uri?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;


    location ~ \.php(.*)$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_split_path_info  ^((?U).+\.php)(/?.+)$;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO  $fastcgi_path_info;
        fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

一些说明

在伪静态配置用try_files而非rewrite,是因为rewrite会对全部匹配(这里是 /)请求都做一次匹配,如:host.com/a.png,这会会浪费一些资源(服务器的算力等);同时也参考了laravel的官方配置加入一些安全设置。

如果在用到上线项目时最好加入静态资源缓存配置。

    location ~* ^.+\.(css|js|ico|gif|jpg|jpeg|png)$ {
        expires 30d;
    }

修复

2020-08-20 发现get没有参数,原因是没有QUERY_STRING为空,解决:

    location / {
        # 带上 query_string
        try_files $uri $uri/ /index.php$uri?$query_string;
    }
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 3年前 自动加精
讨论数量: 3

一直使用都 tp 提供的

location / {
            # Redirect everything that isn't a real file to index.php
            #try_files $uri $uri/ /index.php$is_args$args;
            if (!-e $request_filename) {
                rewrite  ^(.*)$  /index.php?s=/$1  last;
            }
        }
3年前 评论
linzening 3年前
yangweijie 3年前
lmaster (楼主) 3年前

tp里面不是有说明么?

3年前 评论
lmaster

额,我的意思是

fastcgi_param  PATH_INFO  $fastcgi_path_info;
fastcgi_param  PATH_TRANSLATED  $document_root$fastcgi_path_info;

加入这两条

3年前 评论
yzh52521 3年前
魔魔 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!