掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
thinkphp6開啟多應(yīng)用模式(在thinkphp5對(duì)應(yīng)的是多模塊),假設(shè)我們?cè)O(shè)置home應(yīng)用為前臺(tái)模塊,admin為后臺(tái)模塊,api為api接口模塊,common為公共數(shù)據(jù)處理模塊。那么網(wǎng)站前臺(tái)的訪問路徑可能是這樣的:
http://m.askgenny.com/home/project/view/id/21.html
可以通過路由規(guī)則重寫,如這樣的代碼
Route::get('/item/:id', 'home/project/view');
這樣上面開頭的鏈接會(huì)變成:
http://m.askgenny.com/item/21.html
實(shí)際上作為用戶前臺(tái)都帶上一個(gè)并沒有多少意義的home/,自然會(huì)影響url的美觀度。雖然可以通過重寫路由規(guī)則來(lái)一個(gè)個(gè)方法來(lái)重寫,但是這個(gè)下面這個(gè)路徑:
http://m.askgenny.com/home/index/index.html
即便通過路由規(guī)則重寫,如這樣的代碼:
Route::get('/', 'home/index/index');
生成的地址是這樣的:
http://m.askgenny.com/home/
而且路由規(guī)則重新我們需要針對(duì)一個(gè)個(gè)方法分別重新,那么有沒有什么辦法不管是什么路徑都可以統(tǒng)一完成重寫呢?也就是在默認(rèn)路由生成的url中去掉應(yīng)用的名稱(如home)呢?
答案當(dāng)然是有的!當(dāng)然,thinkphp6的設(shè)計(jì)理念就已經(jīng)不再是面向后臺(tái)和前端融合在一起的傳統(tǒng)開發(fā)方式,而是針對(duì)前后端分離開發(fā)而設(shè)計(jì)的,比如最典型的就是已經(jīng)把session給禁用了,而是用一種類似cache的方式來(lái)模擬實(shí)現(xiàn)session。但是,實(shí)際上thinkphp6用來(lái)做非前后端分離的應(yīng)用也是可以的。首先說明的是,這篇文章雖然是針對(duì)最新的tinkphp6,但對(duì)于thinkphp5也具有參考意義。
方法一:應(yīng)用綁定域名
通過config/app.php來(lái)配置多域名,設(shè)置domain_bind,如這樣設(shè)置:
// 域名綁定(自動(dòng)多應(yīng)用模式有效) 'domain_bind'=> [ 'www'=>'home', 'sys'=>'admin', 'api'=>'api' ],
這樣訪問www這個(gè)子域名就可以訪問home應(yīng)用,而且url中會(huì)自動(dòng)去掉home。這種方式也是框架設(shè)計(jì)就預(yù)留的一種方式,配置過程是相對(duì)簡(jiǎn)單的,但前提是這個(gè)站點(diǎn)必須同時(shí)綁定多個(gè)域名(如果有多個(gè)可通過url訪問的應(yīng)用)。那么如果只能綁定一個(gè)域名,而且同時(shí)要滿足多應(yīng)用呢是否可以呢?答案是可以的,但前提是admin和api應(yīng)用的url中不需要?jiǎng)h除對(duì)應(yīng)的應(yīng)用名稱,否則某些路徑可能跟home應(yīng)用混淆了,下面兩種方法就是實(shí)現(xiàn)的兩種方式。
方法二:前臺(tái)應(yīng)用直接使用app根目錄的應(yīng)用
也就是控制器目錄直接是app\controller,而其他的應(yīng)用則分別是app\應(yīng)用名(如admin)\controller,這種雖然看上去有點(diǎn)不倫不類,但這樣確實(shí)就不存在對(duì)應(yīng)的應(yīng)用名稱的。但是,如果需要在其他應(yīng)用中生成前臺(tái)應(yīng)用的url就會(huì)出現(xiàn)異常,比如在后臺(tái)文章列表中需要生成一個(gè)文章前臺(tái)訪問的網(wǎng)址。這時(shí)候假設(shè)url寫法是這樣的:
url('posts/view',['id'=>1])
我們預(yù)期要生成的url是
posts/view/id/1.html
但實(shí)際上thinkphp會(huì)自動(dòng)認(rèn)為這個(gè)url是后臺(tái)這個(gè)應(yīng)用的路由,于是就變成了
admin/posts/view/id/1.html
那怎么辦呢?還是有辦法的,那就是在后臺(tái)生成前臺(tái)應(yīng)用的url的時(shí)候,不使用thinkphp自帶的url助手方法,自己重寫一個(gè)方法,如home_url。
function home_url($path,$vars=[]){ $string=url(strtolower($path),$vars,true,false)->build(); $defalutModule = 'home'; $search = '/'.$defalutModule.'/'; $pos = stripos($string, $search); if($pos !== false && substr_count(rtrim($string,'/'), '/') >= 2) { $string = substr($string, 0, $pos).'/'.substr($string, $pos + strlen($search)); } return $string; }
然后在后臺(tái)生成前臺(tái)url的時(shí)候,使用home_url代替url,且在路徑上加上home。
url('home/posts/view',['id'=>1])
這樣就可以生成我們所預(yù)期的url。
方法三:在入口文件指定應(yīng)用
依然創(chuàng)建home應(yīng)用作為網(wǎng)站前臺(tái),前臺(tái)的url生成不使用url,而采用類似方法二中的home_url來(lái)重新url生成規(guī)則。但只是生成不帶home的url,這樣方法肯定會(huì)報(bào)錯(cuò),因?yàn)檫@樣默認(rèn)肯定會(huì)方法app\controller下的控制器了。那么如何使用不含home的url直接訪問到app\home\controller呢。那就是在入口文件(默認(rèn)位于public\index.php),修改如下代碼:
$response = $http->run();
修改為:
$response = $http->name('home')->run();
但是這樣一來(lái)home應(yīng)用是可以正常訪問,但admin、api等其他應(yīng)用訪問肯定是異常的,這時(shí)候需要給admin、api等其他應(yīng)用創(chuàng)建自己的入口文件,比如admin,可以復(fù)制index.php代碼(把其中的home改為admin)另存為admin.php,其他應(yīng)用一樣的道理。但這樣admin、api的路徑都需要修改,如果是新項(xiàng)目還好,如果是已經(jīng)寫好的項(xiàng)目那么就有點(diǎn)麻煩了。其實(shí),如果不需要?jiǎng)h除admin、api等應(yīng)用的url中的應(yīng)用名稱,其實(shí)可以在入口文件中這么寫:
$path=isset($_SERVER['QUERY_STRING'])?$_SERVER['QUERY_STRING']:''; if(stripos($path,'admin')==1 || stripos($path,'api')==1){ $response = $http->run(); }else{ $response = $http->name('home')->run(); }
這段代碼的意思是,如果訪問的路徑是admin或api開頭的,則需要url指定應(yīng)用名稱;而home應(yīng)用則無(wú)需指定應(yīng)用名,英文在入口文件中就已經(jīng)指定了。
方法四:最粗暴的方法,在web服務(wù)器軟件重寫url
首先借鑒方法二中的home_url方法,把home應(yīng)用的url生成為不帶home的url,直接訪問肯定是不行的??梢酝ㄟ^web服務(wù)器軟件(如apache或nginx)進(jìn)行規(guī)則重寫,也就是我們通常所說的服務(wù)器偽靜態(tài)規(guī)則,實(shí)現(xiàn)訪問不帶home的url自動(dòng)指向到app\home\controller下的方法。
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流