成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

CI3設置子目錄控制器為默認控制器的解決辦法

niceforbear / 650人閱讀

摘要:在框架中配置文件多目錄前后臺應該是個很常見的事情。于是在求學問道的途中,終于得到了比較完美的解決方法。業(yè)務需求環(huán)境需求在中實現(xiàn)前后臺的效果。因為已經(jīng)不支持設置子目錄下的控制器為默認控制器的功能。


????在框架中配置文件多目錄、前后臺應該是個很常見的事情。像一般的php框架(CITp等)采用都是單一入口模式,或許有人會直接在框架根目錄新建文件admin.php,然后改變框架app結構,以達到訪問不同入口文件名獲得不同資源的效果。那么在CI中一樣可以這樣做,不過個人覺得這種方法太浪費資源(占用了幾十k的資源吧)。于是在‘求學問道’的途中,終于得到了比較完美的解決方法。

業(yè)務需求

環(huán)境:codeigniter 3
需求:在CI3中實現(xiàn)前后臺的效果。例:

地址欄輸入xxx.com默認訪問前臺主頁,輸入xxx.com/admin訪問后臺

所遇問題

依照慣例,我們會在框架中的config/route.php路由配置文件中配置我們的前后臺訪問路徑:

// path => application/config/route.php

$route["admin"] = "admin/admin"; //后臺路徑
$route["default_controller"] = "home/home"; // 默認前臺路徑
$route["404_override"] = "";
$route["translate_uri_dashes"] = FALSE;

一般來說,我們這樣配置是沒問題的,但是有一個條件就是在CI3以下的版本中是沒任何問題。但是目前的框架版本CI3,所以就會出現(xiàn)找不到資源文件的情況,空口無憑不算,下面是兩張CI2CI3的route的配置圖,和瀏覽器效果圖:

CI2和CI3相同路由配置對比圖:

CI2和CI3相同路由配置運行網(wǎng)頁對比圖:

由上述兩圖可以看到,相同的路由配置下,但是結果卻是不一樣。因為CI3已經(jīng)不支持設置子目錄下的控制器為默認控制器的功能。但是要完成需求描述,這樣的效果該如何實現(xiàn)呢?接下來看我們追蹤CI3源碼;

源碼追蹤core/Route.php

通過上面的結論,我們應該可以聯(lián)想到出現(xiàn)404這樣的報錯,應該是解析default_controller的時候出現(xiàn)的問題,于是我在sublime中利用全文檢索查詢哪里有用到default_controller,搜索的范圍可以假定為在CI核心目錄中,因為路由的解析一般是由核心目錄里的路由類完成的,于是查詢范圍鎖定在system目錄,得出下面的結果:

鎖定_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里面拆分我們在config/route.php里配置好的default_controller值得到控制器名并賦值給變量class方法名并賦值給method,如果method為空則默認為index,很顯然這與我們的初衷不相符,因為我們的計劃是default_controller里的值home/home,第一個home是目錄名(floder_name),第二個home才是控制器名字(controller_name)

而第二段if的意思是判斷控制器文件是否存在,排查也發(fā)現(xiàn)控制器名竟然不存在,打印

APPPATH . "controllers/" . $this->directory . ucfirst($class) . ".php"

得到:E:WWWci3applicationcontrollers/Home.php,這顯然與我們的實際目錄不相符,我們的實際目錄應該是E:WWWci3applicationcontrollers/home/Home.php,鎖定這兩個問題之后,就可以思考如何修正這里了,剛開始對這個地方的改動想法是這樣的:

假定設置默認的控制器值為Home/home/index(目錄名/控制器名/方法名)的形式

修改core/Route.php源碼中的_set_default_controller方法,截取default_controller的值進行處理

修改_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 表示是默認控制器過來的
     * 3.賦值相應的變量
     */
    $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];
        // 因為這里計劃約定默認控制器輸入完整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.");
}

雖說這樣修改測試成功了,但是覺得并不是最好的解決辦法(修改源碼一般是最后的解決手段),于是求助codeigniter中國的官方微信群的小伙伴,在群里和Hex(手動@Hex)老大討論了一下這個功能的解決方案,最終在他的幫助下得到了比較完美的解決方法,就是要在application/core里新建一個自己的擴展路由類MY_Router.php,然后定義自己的_set_default_controller方法,代碼如下,順便貼上自己上面設想的解決方法:

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)用設置控制器目錄方法 詳細參考system/core/Route.php set_directory方法
         * 3.接著再把method拆分 賦值給$class $method $method為空則設置為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)
     * 
     * 使用這個方法時 把這個方法名和上面的方法名調(diào)換一下 
     * application/config/route.php default_controller的值寫uri全稱(目錄名/控制器名/方法名) 即可
     * 因為最終Route.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 表示是默認控制器過來的
         * 3.賦值相應的變量
         */
        $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];
            // 因為這里計劃約定默認控制器輸入完整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.");
    }

}

以上代碼比較完美的那個,親測有效!?。?自己的這個簡單測試了一下,也可以使用)

資源 參考文章

How to select default controller in subfolder?

How to use a sub folder in default controller route in CodeIgniter 3

資源

MY_Route.php

CodeIgniter中國微信群

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/25585.html

相關文章

  • 視頻直播常見問題與解決辦法匯總【系列二—直播截圖】

    摘要:常見問題直播截圖是針對于推流的為粒度設置的,用戶可以設置某個下的所有的截圖規(guī)則。 摘要: 使用場景 用戶常需要對視頻直播的內(nèi)容進行分析。例如,需要對直播中的某一幀的內(nèi)容作為封面圖片或者對于直播內(nèi)容進行鑒黃以查看內(nèi)容合法性等需求。因此,視頻直播提供了實時截圖功能滿足用戶的截圖需求。 截圖功能介紹 截圖功能配置 配置視頻直播的截圖功能可以通過兩種方法: 通過控制臺創(chuàng)建:詳情參考 控制臺配置...

    piapia 評論0 收藏0
  • 轉(zhuǎn)載:瀏覽器常見兼容問題以及解決辦法

    摘要:瀏覽器兼容問題四行內(nèi)屬性標簽,設置后采用布局,又有橫行的的情況,間距問題癥狀里的間距比超過設置的間距碰到幾率解決方案在后面加入備注行內(nèi)屬性標簽,為了設置寬高,我們需要設置除了標簽比較特殊。 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補丁和內(nèi)補丁不同問題癥狀:隨便寫幾個標簽,不加樣式控制的情況下,各自的margin 和padding差異較大。碰到頻率:100%解決方案:CSS里 *...

    AaronYuan 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<