Nginx在动态之前提供静态页面

时间:2016-04-22 21:46:11

标签: php nginx

我想用NGINX提供静态HTML文件,但是如果文件丢失,它应该加载PHP文件而PHP应该处理内容。

我一直在测试try_files的几种组合,但我无法理解它。我有一个虚拟的PHP应用程序,如下所示:

./
../
dynamic.php
index.php
static/
static/static.html

然后我在索引上有一个小的PHP代码:

<?php

$path = $_SERVER['REQUEST_URI'];
$pattern = '/^\/(.*)\.html$/';

$matches = [];

$results = preg_match($pattern, $path, $matches);

if (count($matches) > 0) {
    if ($matches[1] == "dynamic") {
        require 'dynamic.php';
    } else {
        echo "Not found!";
    }
} else {
    echo "Index page!";
}

浏览每个页面的结果应为:

http://foo.bar/             - Loads index.php
http://foo.bar/static.html  - Loads static/static.html
http://foo.bar/dynamic.html - Loads index.php & PHP requires dynamic.php
http://foo.bar/baz.html     - Loads index.php with "not found" message

这是我在NGINX配置文件中得到的:

server {
    listen 80;
    server_name .foo.bar *.foo.bar;

    access_log /var/log/nginx/foo.access.log;
    error_log  /var/log/nginx/foo.error.log;

    root /var/www/foo;
    index index.php;

    location / {
        # Trying with 'try_files' here. No success.
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

我一直在反复尝试,显然完全失败了这条线:

try_files $uri $uri/static /index.php;

我错过了什么。帮助

3 个答案:

答案 0 :(得分:7)

有多种方法可以隐藏URL中的static目录。例如,操纵root,巧妙使用try_filesrewrite

可能最明显的是:

root /var/www/foo;

location / {
    root /var/www/foo/static;
    try_files $uri /index.php;
}

location ~ \.php$ { ... }

以便nginxstatic文件夹中查找普通文件,但查找.php个文件的父文件夹。

你想要达到的目标是这样的:

root /var/www/foo;

location / {
    try_files /static$uri /index.php;
}

location ~ \.php$ { ... }

在测试存在之前将/static前缀到任何URI。 /index.php必须是最后一个元素,因为它需要在不同位置进行处理。有关详情,请参阅this document

答案 1 :(得分:6)

我会将您的静态目录用作文档根目录。这可以确保没有人可以直接执行/dynamic.php,但是,它会通过指定的位置块index.php转发到您的@php

  

此配置示例未经测试!

server {
    index       index.php;
    root        /var/www/foo/static;
    server_name foo.bar *.foo.bar;

    location / {
        try_files $uri @php;
    }

    location @php {
        include fastcgi_params;

        fastcgi_pass  unix:/var/run/php5-fpm-foo.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME /var/www/foo/index.php;
    }
}
  1. 如果它只包含80,则不需要listen指令,因为这是默认值。
  2. server_name s不应包含前导点。
  3. $uri始终包含请求的URI,包括前导斜杠(例如/static.html),nginx将在调用try_files时为文档根添加前缀(例如/var/www/foo/static.html )。因此,您需要在static之前设置$uri目录(例如/static$uri变为/var/www/foo/static/static.html)。
  4. 您不需要fastcgi_split_path_info,因为您没有使用该功能。
  5. 您的PHP位置try_files使得nginx无法正确转发内容。对/dynamic.html的请求不会在.php上结束,因此,try_files始终会失败。

答案 2 :(得分:1)

根据您提供的具体示例,下面的配置将返回您列出的结果。

server {
    listen 80;
    server_name .foo.bar *.foo.bar;

    access_log /var/log/nginx/foo.access.log;
    error_log  /var/log/nginx/foo.error.log;

    root /var/www/foo;
    index index.php;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php5-fpm-foo.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /static {
        rewrite ^/static\.html$ /static/ last;
        index static.html;
    }
    location ~ / {
        rewrite ^ /index.php last;
    }

那是......

http://foo.bar/             - Loads index.php
http://foo.bar/static.html  - Loads static/static.html
http://foo.bar/dynamic.html - Loads index.php & PHP requires dynamic.php
http://foo.bar/baz.html     - Loads index.php with "not found" message