摘要:在框架中配置文件多目錄前后臺(tái)應(yīng)該是個(gè)很常見的事情。于是在求學(xué)問道的途中,終于得到了比較完美的解決方法。業(yè)務(wù)需求環(huán)境需求在中實(shí)現(xiàn)前后臺(tái)的效果。因?yàn)橐呀?jīng)不支持設(shè)置子目錄下的控制器為默認(rèn)控制器的功能。
????在框架中配置文件多目錄、前后臺(tái)應(yīng)該是個(gè)很常見的事情。像一般的php框架(CI、Tp等)采用都是單一入口模式,或許有人會(huì)直接在框架根目錄新建文件admin.php,然后改變框架app結(jié)構(gòu),以達(dá)到訪問不同入口文件名獲得不同資源的效果。那么在CI中一樣可以這樣做,不過個(gè)人覺得這種方法太浪費(fèi)資源(占用了幾十k的資源吧)。于是在‘求學(xué)問道’的途中,終于得到了比較完美的解決方法。
業(yè)務(wù)需求環(huán)境:codeigniter 3
需求:在CI3中實(shí)現(xiàn)前后臺(tái)的效果。例:
所遇問題地址欄輸入xxx.com默認(rèn)訪問前臺(tái)主頁,輸入xxx.com/admin訪問后臺(tái)
依照慣例,我們會(huì)在框架中的config/route.php路由配置文件中配置我們的前后臺(tái)訪問路徑:
// path => application/config/route.php $route["admin"] = "admin/admin"; //后臺(tái)路徑 $route["default_controller"] = "home/home"; // 默認(rèn)前臺(tái)路徑 $route["404_override"] = ""; $route["translate_uri_dashes"] = FALSE;
一般來說,我們這樣配置是沒問題的,但是有一個(gè)條件就是在CI3以下的版本中是沒任何問題。但是目前的框架版本是CI3,所以就會(huì)出現(xiàn)找不到資源文件的情況,空口無憑不算,下面是兩張CI2和CI3的route的配置圖,和瀏覽器效果圖:
CI2和CI3相同路由配置對(duì)比圖: CI2和CI3相同路由配置運(yùn)行網(wǎng)頁對(duì)比圖:由上述兩圖可以看到,相同的路由配置下,但是結(jié)果卻是不一樣。因?yàn)?b>CI3已經(jīng)不支持設(shè)置子目錄下的控制器為默認(rèn)控制器的功能。但是要完成需求描述,這樣的效果該如何實(shí)現(xiàn)呢?接下來看我們追蹤CI3源碼;
源碼追蹤core/Route.php通過上面的結(jié)論,我們應(yīng)該可以聯(lián)想到出現(xiàn)404這樣的報(bào)錯(cuò),應(yīng)該是解析default_controller的時(shí)候出現(xiàn)的問題,于是我在sublime中利用全文檢索查詢哪里有用到default_controller,搜索的范圍可以假定為在CI的核心目錄中,因?yàn)槁酚傻慕馕鲆话闶怯?strong>核心目錄里的路由類完成的,于是查詢范圍鎖定在system目錄,得出下面的結(jié)果:
鎖定_set_default_controller方法
于是我一步一步排查,最終發(fā)現(xiàn)是這一段代碼的問題:
// Is the method being specified? if (sscanf($this->default_controller, "%[^/]/%s", $class, $method) !== 2) { $method = "index"; } if ( ! file_exists(APPPATH."controllers/".$this->directory.ucfirst($class).".php")) { // This will trigger 404 later return; }
上面的代碼第一段if里面拆分我們?cè)?b>config/route.php里配置好的default_controller值得到控制器名并賦值給變量class和方法名并賦值給method,如果method為空則默認(rèn)為index,很顯然這與我們的初衷不相符,因?yàn)槲覀兊挠?jì)劃是default_controller里的值home/home,第一個(gè)home是目錄名(floder_name),第二個(gè)home才是控制器名字(controller_name)
而第二段if的意思是判斷控制器文件是否存在,排查也發(fā)現(xiàn)控制器名竟然不存在,打印
APPPATH . "controllers/" . $this->directory . ucfirst($class) . ".php"
得到:E:WWWci3applicationcontrollers/Home.php,這顯然與我們的實(shí)際目錄不相符,我們的實(shí)際目錄應(yīng)該是E:WWWci3applicationcontrollers/home/Home.php,鎖定這兩個(gè)問題之后,就可以思考如何修正這里了,剛開始對(duì)這個(gè)地方的改動(dòng)想法是這樣的:
假定設(shè)置默認(rèn)的控制器值為Home/home/index(目錄名/控制器名/方法名)的形式
修改core/Route.php源碼中的_set_default_controller方法,截取default_controller的值進(jìn)行處理
修改_set_default_controller方法如下:
protected function _set_default_controller() { if (empty($this->default_controller)) { show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file."); } /** * if里為自己修改的部分 * 1.截取default_controller為數(shù)組 * 2.如果default_controller_arr大于3 表示是默認(rèn)控制器過來的 * 3.賦值相應(yīng)的變量 */ $default_controller_arr = explode("/", $this->default_controller); if(count($default_controller_arr) == 3) { // 賦值控制器所在目錄 $this->directory = trim($default_controller_arr[0], "/") . "/"; // 賦值控制器名 $class = $default_controller_arr[1]; // 因?yàn)檫@里計(jì)劃約定默認(rèn)控制器輸入完整uri 即目錄名/控制器名/方法名的形式 // 所以方法名這里一定不為空 $method = $default_controller_arr[2]; }else { // Is the method being specified? if (sscanf($this->default_controller, "%[^/]/%s", $class, $method) !== 2) { $method = "index"; } } if ( ! file_exists(APPPATH."controllers/".$this->directory.ucfirst($class).".php")) { // This will trigger 404 later return; } $this->set_class($class); $this->set_method($method); // Assign routed segments, index starting from 1 $this->uri->rsegments = array( 1 => $class, 2 => $method ); log_message("debug", "No URI present. Default controller set."); }
雖說這樣修改測(cè)試成功了,但是覺得并不是最好的解決辦法(修改源碼一般是最后的解決手段),于是求助codeigniter中國的官方微信群的小伙伴,在群里和Hex(手動(dòng)@Hex)老大討論了一下這個(gè)功能的解決方案,最終在他的幫助下得到了比較完美的解決方法,就是要在application/core里新建一個(gè)自己的擴(kuò)展路由類MY_Router.php,然后定義自己的_set_default_controller方法,代碼如下,順便貼上自己上面設(shè)想的解決方法:
default_controller)) { show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file."); } if (sscanf($this->default_controller, "%[^/]/%s", $class, $method) !== 2) { $method = "index"; } /** * 1.判斷目錄是否存在 * 2.如果存在 調(diào)用設(shè)置控制器目錄方法 詳細(xì)參考system/core/Route.php set_directory方法 * 3.接著再把method拆分 賦值給$class $method $method為空則設(shè)置為index */ if( is_dir(APPPATH."controllers/".$class) ) { // Set the class as the directory $this->set_directory($class); // $method is the class $class = $method; // Re check for slash if method has been set if (sscanf($method, "%[^/]/%s", $class, $method) !== 2) { $method = "index"; } } if ( ! file_exists(APPPATH."controllers/".$this->directory.ucfirst($class).".php")) { // This will trigger 404 later return; } $this->set_class($class); $this->set_method($method); // Assign routed segments, index starting from 1 $this->uri->rsegments = array( 1 => $class, 2 => $method ); log_message("debug", "No URI present. Default controller set."); } /** * @author 命中水、 * @date(2017-8-7) * * 使用這個(gè)方法時(shí) 把這個(gè)方法名和上面的方法名調(diào)換一下 * application/config/route.php default_controller的值寫uri全稱(目錄名/控制器名/方法名) 即可 * 因?yàn)樽罱KRoute.php路由類庫調(diào)用的還是_set_default_controller方法 */ protected function _set_default_controller_me() { if (empty($this->default_controller)) { show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file."); } /** * if里為自己修改的部分 * 1.截取default_controller為數(shù)組 * 2.如果default_controller_arr大于3 表示是默認(rèn)控制器過來的 * 3.賦值相應(yīng)的變量 */ $default_controller_arr = explode("/", $this->default_controller); if(count($default_controller_arr) == 3) { // 賦值控制器目錄 $this->directory = trim($default_controller_arr[0], "/") . "/"; // 賦值控制器名 $class = $default_controller_arr[1]; // 因?yàn)檫@里計(jì)劃約定默認(rèn)控制器輸入完整uri 即目錄名/控制器名/方法名的形式 // 所以方法名這里一定不為空 $method = $default_controller_arr[2]; }else { if (sscanf($this->default_controller, "%[^/]/%s", $class, $method) !== 2) { $method = "index"; } } if ( ! file_exists(APPPATH."controllers/".$this->directory.ucfirst($class).".php")) { // This will trigger 404 later return; } $this->set_class($class); $this->set_method($method); // Assign routed segments, index starting from 1 $this->uri->rsegments = array( 1 => $class, 2 => $method ); log_message("debug", "No URI present. Default controller set."); } }
以上代碼比較完美的那個(gè),親測(cè)有效!!!(自己的這個(gè)簡(jiǎn)單測(cè)試了一下,也可以使用)
資源 參考文章How to select default controller in subfolder?
How to use a sub folder in default controller route in CodeIgniter 3
資源MY_Route.php
CodeIgniter中國微信群
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/25585.html
摘要:常見問題直播截圖是針對(duì)于推流的為粒度設(shè)置的,用戶可以設(shè)置某個(gè)下的所有的截圖規(guī)則。 摘要: 使用場(chǎng)景 用戶常需要對(duì)視頻直播的內(nèi)容進(jìn)行分析。例如,需要對(duì)直播中的某一幀的內(nèi)容作為封面圖片或者對(duì)于直播內(nèi)容進(jìn)行鑒黃以查看內(nèi)容合法性等需求。因此,視頻直播提供了實(shí)時(shí)截圖功能滿足用戶的截圖需求。 截圖功能介紹 截圖功能配置 配置視頻直播的截圖功能可以通過兩種方法: 通過控制臺(tái)創(chuàng)建:詳情參考 控制臺(tái)配置...
摘要:瀏覽器兼容問題四行內(nèi)屬性標(biāo)簽,設(shè)置后采用布局,又有橫行的的情況,間距問題癥狀里的間距比超過設(shè)置的間距碰到幾率解決方案在后面加入備注行內(nèi)屬性標(biāo)簽,為了設(shè)置寬高,我們需要設(shè)置除了標(biāo)簽比較特殊。 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)丁和內(nèi)補(bǔ)丁不同問題癥狀:隨便寫幾個(gè)標(biāo)簽,不加樣式控制的情況下,各自的margin 和padding差異較大。碰到頻率:100%解決方案:CSS里 *...
閱讀 3723·2021-11-24 09:39
閱讀 1870·2021-11-16 11:45
閱讀 616·2021-11-16 11:45
閱讀 1029·2021-10-11 10:58
閱讀 2475·2021-09-09 11:51
閱讀 1941·2019-08-30 15:54
閱讀 687·2019-08-29 13:13
閱讀 3466·2019-08-26 12:18