dongtuo7364 2013-09-20 16:02
浏览 84
已采纳

使用PHP模拟“假”目录,不使用.htaccess,mod_rewrite或404重定向

Situation

Hello, I'm confused as to PHP's expected/default behavior regarding extensionless PHP files, and/or URL requests that "go past" the actual file that (I want to) processes the request (i.e., PHP's default "fallback" actions before it resorts to completely 404-ing). Here's my situation:

My directory structure on my local server (running nginx 1.5.3 with very basic PHP 5.5.1 setup) looks like the following:

/index
/index.php
/other
/other.php
/rootdir/index
/rootdir/index.php
/rootdir/other
/rootdir/other.php

The contents of all eight files are the same:

<?php
echo $_SERVER['PHP_SELF'] . ', ' . $_SERVER['REQUEST_URI'];
?>

BUT, hitting the respective endpoint produces some strange (to me) results.

Research

GET /index.php
'/index.php, /index.php' # Makes sense...

GET /index.php/something_else
'/index.php, /index.php/something_else' # Also makes sense...

GET /index/something_else
'/index.php, /index/something_else' # Let's call this ANOMALY 1... (see below)

GET /something_else
'/index.php, /something_else' # ANOMALY 2

GET /other.php
'/other.php, /other.php' # Expected...

GET /other.php/something_else
'/index.php, /other.php/something_else' # ANOMALY 3

GET /rootdir/index.php
'/rootdir/index.php, /rootdir/index.php' # Expected...

GET /rootdir/index.php/something_else
'/index.php, /rootdir/index.php/something_else' # ANOMALY 4

GET /rootdir/other.php
'/rootdir/other.php, /rootdir/other.php' # Expected...

GET /rootdir/other.php/something_else
'/index.php, /rootdir/other.php/something_else' # ANOMALY 5

My understanding is that the server redirects to /index.php when it is unable to find what the user is looking for at the request URI; that much makes sense... what I don't understand is:

  1. Why it will do this despite my not having a dedicated 404 page set up (I didn't tell it to try /index.php before 404-ing; I want it to display a legit, non-custom 404 page if something isn't found and/or can't be processed. I figured it should display the default server 404 page when it couldn't find something... apparently that's not always the case...?)
  2. Why it doesn't try /rootdir/index.php when it can't find something within the /rootdir/ subdirectory.

Questions

  1. Would somebody be able to shed some light on what PHP's logic is (or maybe it's nginx's doing; I haven't been able to figure that out yet) with regards to addresses that are not found? Why am I seeing what I am seeing? (Specifically with respect to Anomalies #4 and #5. I expected it to use /rootdir/index.php for handling it's "404," or I expected a real 404 page; the fallback to /index.php was unexpected.)

  2. As a direct corollary (corollical?) question, how can I go about simulating extensionless PHP files that will handle hits that occur "below" them (e.g. in the Anomaly #1 case; that's actually exactly what I want, though it wasn't quite what I expected) without relying on .htaccess, mod_rewriting, or redirects? Or is that a silly question? :-)

References

I'm trying to roll out a custom implementation for handling requests like /some_dir/index.php/fake_subdir and /some_other_dir/index.php/fake_subdir (i.e., different "fallback handlers") without relying on Apache, but the logic behind PHP's (or nginx's?) default fallback behavior is eluding me. These pages are primarily where this question stems from:

  • 写回答

2条回答 默认 最新

  • doujie7346 2013-09-20 21:59
    关注

    Well, I figured out what was going on: I had a misconfigured nginx server.

    Marc B's answer, though related to Apache, prompted me to check out my PATH_INFO value — lo and behold, PATH_INFO was nonexistent, even for requests like GET /other.php/something_else.

    Some more searching turned up the answer. Using nginx's fastcgi_split_path_info to split the URI into a) the path to the script and b) the path that appears following the script name will fail if done after a use of the try_files directive, due to its rewriting the URI to point to a file on the disk. This obliterates any possibility of obtaining a PATH_INFO string.

    As a solution, I did three things (some of these are probably redundant, but I did them all, just in case):

    1. In a server's location block, make use of fastcgi_split_path_info before setting up PATH_INFO via

      fastcgi_param PATH_INFO $fastcgi_path_info;
      

      ...and do both before making use of try_files.

    2. Store $fastcgi_path_info as a local variable in case it ever changes later (e.g. with set $path_info $fastcgi_path_info;)

    3. When using try_files, don't use $uri... use $fastcgi_script_name. (Pretty sure this was my biggest mistake.)

    Sample Configuration

    server {
    
        # ... *snip* ...
    
        location ~ \.php {
            # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
    
            include fastcgi_params;
    
            fastcgi_index index.php;
            fastcgi_intercept_errors on;
            fastcgi_pass 127.0.0.1:9000;
    
            try_files $fastcgi_script_name =404;
        }
    
        # ... *snip* ...
    
    }
    

    Where fastcgi_params contains:

    set            $path_info         $fastcgi_path_info;
    fastcgi_param  PATH_INFO          $path_info;
    fastcgi_param  PATH_TRANSLATED    $document_root$path_info;
    
    fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
    fastcgi_param  SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    
    # ... *snip* ...
    

    Reference

    The following links explain the problem pretty well and provide an alternate nginx configuration:

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 maixpy训练模型,模型训练好了以后,开发板通电会报错,不知道是什么问题
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 有没有帮写代码做实验仿真的
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥30 vmware exsi重置后登不上
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容