TP5專案放在二級目錄下重定向訪問不對問題
阿新 • • 發佈:2018-11-08
最近用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從而可以正確訪問。