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条)

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?