douwei7976
2018-04-12 05:00
浏览 226
已采纳

NGINX将路径作为变量发送给PHP,除非路径是文件路径

I want to pass all my path to index.php?page=path. For example:

domain.com/a/b/c -> index.php?page=a/b/c

Therefore this is my NGINX conf file:

location ~ /(?P<arg1>.*)$ {
    fastcgi_pass php:9000;
    fastcgi_param  QUERY_STRING       /index.php?page=$arg1;
}

As far as I know, query string should be everything after .com, right? I'm passing arg1 to it. However, I wanted to ignore truly file paths like /file.jpg or /images/favicon.ico. I could simply negate them in regex but then they'd have no path at all.

So how to match /anything to index.php?page=anything except for files and actually deliver those files?

图片转代码服务由CSDN问答提供 功能建议

我想将所有路径传递给index.php?page = path。 例如:

  domain.com/a/b/c  - &gt;  index.php?page = a / b / c 
   
 
 

因此这是我的NGINX配置文件:

   location~ /(?P<arg1>.*)$ {
 fastcgi_pass php:9000; 
 fastcgi_param QUERY_STRING /index.php?page=$arg1;
}

据我所知,查询字符串应该是.com后的所有内容,对吧? 我把arg1传给了它。 但是,我想忽略真正的文件路径,如 /file.jpg /images/favicon.ico 。 我可以在正则表达式中简单地否定它们但是它们根本就没有路径。

那么如何将 / anything index.php相匹配? page =任何除了文件并实际提供这些文件?

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • duanchi8836 2018-05-18 06:32
    已采纳

    You need to use below

    location ~ /(.*)$ {
      try_files $uri $uri/ /index.php?page=$1;
    }
    

    This will first check if file or directory exists if not then pass it to the index.php file

    已采纳该答案
    评论
    解决 无用
    打赏 举报
  • dongyuli4538 2018-05-18 06:14

    Based on your Apache's .htaccess, the equivalent setting under Nginx would be:

        location / {
            # First attempt to serve request as file, then
            # as directory, then index.php?page=$args.
            try_files $uri $uri/ /index.php?page=$args;
        }
    
    评论
    解决 无用
    打赏 举报
  • dsykx64220 2018-05-22 16:57

    I don't know nginx, but assuming truly/real path is something that ends with some kind of extension, and that you can write several rules with top rules having higher priority, you could write 2 rules like these:

    First rule matches an url that ends with an extension: ( dot + word ) and does nothing:

    /^.*[.]\w+$/
    

    second rule matches anything and captures:

    /(.*)/
    

    If that is not possible, you could try to use a rule that matches urls like these: foo/bar/foo/bar/...

    (\w+(?:\/\w+)*\/?)
    

    If you don't want to allow last / bar, just use

    (\w+(?:\/\w+)*)
    
    评论
    解决 无用
    打赏 举报
  • douman6679 2018-05-24 15:58

    The use case you mention is very common, and it's detailed in the common Nginx pitfalls page under the section Front Controller Pattern Web Apps

    As per the aforementioned page, for Drupal, Joomla, etc., just use this inside your location block:

    try_files $uri $uri/ /index.php?q=$uri&$args;
    

    Since you want to use the "page" variable name, your code will look as follows:

    location / {
        try_files $uri $uri/ /index.php?page=$uri&args;
    }
    

    The part $uri/ is relevant only if you want to serve content from directories, for example if you want to serve a Wordpress blog from yourdomain.com/blog/. If that's not the case, you can remove the $uri/ part.

    My advice is to not use page as the variable to pass the section/route to PHP, because you might end up having a confusion between which section of the website to show vs. which page number. Page is misleading, I'd use route instead.

    Of course, your mileage may vary and you may require something more complex based on your needs, but for basic sites, these will work perfectly. You should always start simple and build from there.

    Additionally, to make debugging easier, consider using a verbose error log setting, I'd use info or notice to debug routing:

    error_log logs/error.log info;
    

    Good luck and keep us posted on how you solved the issue.

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题