通过 Nginx 别名提供 PHP 服务

通过 Nginx 别名提供 PHP 服务

我正在将几个网站从 Apache 迁移到 Nginx,在其中一个有虚拟目录(别名)的网站中遇到了问题。别名本身运行良好,并且提供了正确的文件,但 PHP 代理不正确。

server {
  listen      443 default_server ssl;
  server_name dev.myproject.mydomain.net;
  root        /opt/dev/project-root;
  index       index.php;

  ssl_certificate      /etc/ssl/certs/server.crt;
  ssl_certificate_key  /etc/ssl/certs/server.pem;

  access_log /var/log/nginx/vh.project.access.log;
  error_log  /var/log/nginx/vh.project.error.log;

  location ~ ^/alias_name/(.*) {
    alias /opt/dev/project-root/www/$1;

    location ~ ^/alias_name/(.+\.php)$ {
      alias /opt/dev/project-root/www/$1;
      include /etc/nginx/conf/php;
    }
  }

  location ~ \.php$ {
    include /etc/nginx/conf/php;
  }
}

我还没有尝试过,但我怀疑如果我将\.php$位置块的内容复制到别名块中,事情会正常进行,但我内心的工程师讨厌复制。有什么方法可以避免这种情况(假设它可以工作)?直观地说,似乎两个位置块都会被评估。

我确信,我还可以将 php 块移出到单独的文件并将其包含在内。

任何关于处理此问题的最佳方法(阅读:最 nginx-y)的建议都将非常感激。

更新

根据 Kyle 的回答,我已将 PHP 代理移至单独的conf/目录。该conf/php文件包含以下代码:

location ~ \.php$ {
  fastcgi_split_path_info ^(.+\.php)(/.+)$;
  fastcgi_pass 127.0.0.1:9000;
  fastcgi_index index.php;
  include fastcgi_params;
}

我的别名位置块现在如下所示:

location ~ ^/alias_name/(.*) {
  alias /opt/dev/path/to/aliased/$1;
  include /etc/nginx/conf/php;
}

如果我在该别名处放置一个静态 HTML 文件,它会正常呈现。PHP 文件会返回 404。

更新

在评论中@quanta 的帮助下,我设法让 PHP 正常运行,并使用配置更新了别名位置块。不幸的是,如果 URL 包含别名,则不会呈现非静态内容。今天不是我的日子。

答案1

好吧,一旦我整合了 @quanta 的信息(参见上面的评论),我可能已经通过强力反复试验找到了自己的答案。这个虚拟主机服务器块似乎支持 PHP静态内容正确:

server {
  listen      443 default_server ssl;
  server_name dev.myproject.mydomain.net;
  root        /opt/dev/project-root;
  index       index.php;

  ssl_certificate      /etc/ssl/certs/server.crt;
  ssl_certificate_key  /etc/ssl/certs/server.pem;

  access_log /var/log/nginx/myproject.dev.access.log;
  error_log  /var/log/nginx/myproject.dev.error.log;

  location ~ ^/alias_name/(.+\.php)$ {
    alias /opt/dev/project-root/www/$1;
    include /etc/nginx/conf/php;
  }
  location ~ ^/alias_name/(.*) {
    alias /opt/dev/project-root/www/$1;
  }

  location ~ \.php$ {
    include /etc/nginx/conf/php;
  }
}

我不知道我是否会遇到问题,也不能说我完全理解其中的区别,但简单地删除嵌套的location块似乎就可以解决问题。

答案2

您可以将 php 块放在外部包含中,然后执行此操作,我对包含命令不是 100% 确定,但这应该可行。

server {
  listen      443 default_server ssl;
  server_name dev.myproject.mydomain.net;
  root        /opt/dev/project-root;
  index       index.php;

  ssl_certificate      /etc/ssl/certs/server.crt;
  ssl_certificate_key  /etc/ssl/certs/server.pem;

  access_log /var/log/nginx/vh.project.access.log;
  error_log  /var/log/nginx/vh.project.error.log;

  location ~ ^/alias_name/(.*) {
    alias /opt/dev/path/to/aliased/$1;
    include php.inc
  }

  # include defualt location
include php.inc
}

php.inc

  # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
  #
  location ~ \.php$ {
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    include fastcgi_params;
  }

相关内容