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

Apo*_*llo 20 php nginx

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

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

./
../
dynamic.php
index.php
static/
static/static.html
Run Code Online (Sandbox Code Playgroud)

然后我在索引上有一个小的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!";
}
Run Code Online (Sandbox Code Playgroud)

浏览每个页面的结果应该是:

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
Run Code Online (Sandbox Code Playgroud)

这是我在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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

try_files $uri $uri/static /index.php;
Run Code Online (Sandbox Code Playgroud)

我错过了什么.救命?

Ric*_*ith 7

有许多方法可以static从URL 隐藏目录.例如,操纵root,巧妙使用try_files或a rewrite.

可能最明显的是:

root /var/www/foo;

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

location ~ \.php$ { ... }
Run Code Online (Sandbox Code Playgroud)

这样nginxstatic文件夹中查找普通文件,但文件的父文件夹.php.

你想要实现的是这样的:

root /var/www/foo;

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

location ~ \.php$ { ... }
Run Code Online (Sandbox Code Playgroud)

/static在测试存在之前,它将为任何URI添加前缀.的/index.php必须是最后一个元素,因为它在不同的位置所需要的处理.有关更多信息,请参阅此文


Fle*_*der 7

我会将您的静态目录用作文档根目录.这可以确保没有人可以/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;
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. listen如果它只包含80,则不需要该指令,因为这是默认值.
  2. server_name不是应该包含前导点.
  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. try_files在PHP位置使nginx无法正确转发内容.因此,请求/dynamic.html不会结束.php,try_files总是会失败.