1. 程式人生 > >TP5專案放在二級目錄下重定向訪問不對問題

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模組會報模組不存在錯誤:
模組不存在


我就去排查其原因發現在 rizhi(我的專案目錄)/thinkphp/library/think/Request.php檔案裡面的pathinfo()函式獲取的pathinfo資料不對,當我們把重定向的檔案由/改為?後pathinfo()函式的解析走的是
這裡寫圖片描述
如果我們目錄放在網站根目錄下訪問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'] = (0 === strpos( $_SERVER['PATH_INFO'], '/'.$value)) ? substr( $_SERVER['PATH_INFO'], strlen('/'.$value)) : $_SERVER['PATH_INFO']; } } // $_SERVER['PATH_INFO'] = (0 === 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從而可以正確訪問。