如何在nginx上的子目录中获取Slim PHP Framework路由


How to get Slim PHP Framework routes in a subdirectory on nginx

我正在尝试将 Slim 应用程序移动到子目录,以便可以在 example.com/api/ 访问它,但我在使路由工作时遇到了严重的问题。

主脚本位于 /website/workbench/api/public/index.php ,因此对 example.com/api/project/1 的调用应该命中 API 文件夹。但是,我还需要能够访问example.com的index.html文件(该文件在Angular JS上运行(。

当我转到example.com/api/project/1时,它确实击中了 PHP 脚本 - 我可以var_dump变量并查看它们。但是,路由未生效,并且请求变量似乎为空。

/

etc/nginx/sites-available/workbench

server {
    listen   80; ## listen for ipv4; this line is default and implied
    root /website/workbench;
    index index.php index.html index.htm;
    server_name example.com;
    location / {
        try_files $uri $uri/ index.php?$query_string;
    }
    location /api/ {
        try_files $uri $uri/ /api/public/index.php?$query_string;
    }
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    location ~ '.php$ {
        fastcgi_split_path_info ^(.+'.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param PHP_VALUE "newrelic.appname=workbench";
        include fastcgi_params;
    }
    location ~ /'.ht {
        deny all;
    }
}

(显然example.com被替换为真实域名(

var_dump($_SERVER)的部分输出;

array(34) {
  ["USER"]=>
  string(8) "www-data"
  ["HOME"]=>
  string(8) "/var/www"
  ["FCGI_ROLE"]=>
  string(9) "RESPONDER"
  ["PHP_VALUE"]=>
  string(26) "newrelic.appname=workbench"
  ["QUERY_STRING"]=>
  string(0) ""
  ["REQUEST_METHOD"]=>
  string(3) "GET"
  ["CONTENT_TYPE"]=>
  string(0) ""
  ["CONTENT_LENGTH"]=>
  string(0) ""
  ["SCRIPT_FILENAME"]=>
  string(39) "/website/workbench/api/public/index.php"
  ["SCRIPT_NAME"]=>
  string(21) "/api/public/index.php"
  ["REQUEST_URI"]=>
  string(15) "/api/projects/1"
  ["DOCUMENT_URI"]=>
  string(21) "/api/public/index.php"
  ["DOCUMENT_ROOT"]=>
  string(18) "/website/workbench"
  ["SERVER_PROTOCOL"]=>
  string(8) "HTTP/1.1"
  ["GATEWAY_INTERFACE"]=>
  string(7) "CGI/1.1"
  ["SERVER_SOFTWARE"]=>
  string(11) "nginx/1.4.6"
}

var_dump($_REQUEST)给出一个空数组。

显然,我的设置存在一些惊人的问题,但我正在努力看看是什么!将$query_string更改为$args也没有效果。

很晚了,但是我在站点的根目录中提供静态文件(Angular 应用程序(以及在/api 中提供纤薄的应用程序时遇到了同样的问题。正如你所指出的,Slim 确实需要REQUEST_URI

,而不是其中的/api
server {
 server_name example.com;
    location ~ ^/api/(.*)$ {
           alias /path/to/slim-app/public/;
           try_files $1 $1/ @php;
           index index.php;
    }
    location / {
            root /path/to/your/static/files;
    }
    location @php {
           fastcgi_split_path_info ^(/api)(/.*)$;
           fastcgi_pass localhost:9000;
           fastcgi_index index.php;
           include fastcgi_params;
           fastcgi_param SCRIPT_FILENAME /path/to/slim-app/public/index.php;
           fastcgi_param REQUEST_URI $fastcgi_path_info;
           fastcgi_read_timeout 900;
    }
 }

对我来说,关键在于fastcgi_split_path_info诡计。根据 http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_split_path_info,该操作的作用是将$fastcgi_path_info变量拆分为两个变量,称为$fastcgi_script_name$fastcgi_path_info

当你输入fastcgi_split_path_info ^(/api)(/.*)$;你基本上将$fastcgi_script_name设置为/api,将$fastcgi_path_info设置为/my/route。我发现这足以让 Slim (v3( 按照我想要的方式工作。

但是,我还发现我的默认 Slim 应用程序具有DOCUMENT_URLSCRIPT_NAME变量设置为 index.php 。因此,您也可以设置它们(尽管似乎不需要(:

set $script_name "/index.php";
fastcgi_param DOCUMENT_URI $script_name;
fastcgi_param SCRIPT_NAME $script_name;

我认为您可以从try_files中删除$query_string./api位置添加 root 指令,如下所示:

location /api {
    root /website/workbench/api;
    try_files $uri $uri/ /public/index.php;
}

并使用最终定义为的fastcgi_param SCRIPT_FILENAME参数:

 fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

fastcgi_params文件中。