天天看點

TP5項目放在二級目錄下重定向通路不對問題

最近用Thinkphp5做了一個小網站,發現當PHP版本切換成5.5以上版本後

如果通路位址是全位址 如loacalhost/index/index/index重定向不起作用,提示:No input file specified.

此問題比較好解決,原因是php版本5.5以上項目下的重定向檔案.htaccess的文法不支援,重定向失敗,隻要将檔案代碼改動一下。将第七行的

RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]

換為

RewriteRule ^(.*)$ index.php?$1 [QSA,PT,L]

即可。

但是此問題引出了另外一個問題,我的項目不是放在網站根目錄的,是放在網站根目錄下的二級目錄(假設此目錄名為rizhi),我通路時需要通路位址localhost/rizhi/index/index/index,經過我上面修改後位址會重定向為

localhost/rizhi/index.php?rizhi/index/index/index這樣Tp5核心檔案會去尋找rizhi子產品而不是index子產品會報子產品不存在錯誤:

TP5項目放在二級目錄下重定向通路不對問題

我就去排查其原因發現在 rizhi(我的項目目錄)/thinkphp/library/think/Request.php檔案裡面的pathinfo()函數擷取的pathinfo資料不對,當我們把重定向的檔案由/改為?後pathinfo()函數的解析走的是

TP5項目放在二級目錄下重定向通路不對問題

如果我們目錄放在網站根目錄下通路localhost/index/index/index這裡段代碼會比對一下域名(localhost)後面的字元串是否以/index.php開頭如果是就去掉/index.php傳回剩餘部分字元串不是則直接傳回字元串,是以上傳回值都為index/index/index,thinkphp後續會根據它判斷子產品/控制器/action,可以得到正确結果。

但是如果我們的網站是放在網站二級目錄或者三級(或更多)目錄下,那麼傳回的結果将是錯誤的,假設我的項目放在網站根目錄/aa/bb/目錄下,我的通路方式為localhost/aa/bb/index/index/index,此方法會比對

/aa/bb/index/index/index是否以/aa/bb/index.php開頭,這樣比對不成功不能得到正确的傳回值index/index/index,由此我将這一塊代碼改為

// 分析PATHINFO資訊
            if (!isset($_SERVER['PATH_INFO'])) {
                foreach (Config::get('pathinfo_fetch') as $type) {
                    if (!empty($_SERVER[$type])) {
                        $path = explode('/',$_SERVER['SCRIPT_NAME']);
                        $_SERVER['PATH_INFO'] = $_SERVER[$type];
                        foreach($path as $value){
                            if(!empty($value)){
                                $_SERVER['PATH_INFO'] = ( === strpos( $_SERVER['PATH_INFO'], '/'.$value)) ?
                                    substr( $_SERVER['PATH_INFO'], strlen('/'.$value)) : $_SERVER['PATH_INFO'];
                            }
                        }
//                        $_SERVER['PATH_INFO'] = ( === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ?
//                        substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type];
                        break;
                    }
                }
            }
           

将aa/bb/index.php拆開,分别比對是否以/aa開頭如果是則去除/aa然後再次判斷是否以/bb開頭……直到判斷完為止。這樣就能把/aa、/bb、/index.php全部去除,得到我們想要的index/index/index進而可以正确通路。