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

时间:2014-09-24 10:58:08

标签: php nginx slim

我正在尝试将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的/位点可用/工作台

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也无效。

2 个答案:

答案 0 :(得分:8)

这里的聚会很晚,但我在网站的根目录中提供静态文件(一个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诡计。根据{{​​3}},操作的作用是将$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;

答案 1 :(得分:4)

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

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文件。