最近在使用CodeIgniter開發一個企業站項目,一開始是把前臺和後臺分開做爲兩個單獨的項目,但後來想一想爲啥不能放在一個項目裏呢,便有了改造的想法。php
先上一張最終的目錄結構圖git
application/ |-- config/ | |-- routes.php |-- controllers/ | |-- backend/ | |-- frontend/ |-- core/ | |-- MY_Controller.php | |-- MY_Router.php |-- views/ | |-- backend/ | |-- frontend/ |-- static/ | |-- backend/ | |-- frontend/ |-- index.php
這樣設計的的好處:
一、目錄結構清晰
二、保持了單入口index.phpgithub
controllers/backend和controllers/frontend目錄下的控制器能夠分別繼承不一樣的基類。好比:後臺控制器繼承基類Backend_Controller,前臺控制器繼承基類Frontend_Controller。
MY_Controller擴展核心系統類CI_Controller,能夠根據業務須要添加一些公共功能。
Backend_Controller和Frontend_Controller均繼承自MY_Controller。bash
那麼問題來了,Backend_Controller和Frontend_Controller定義在哪裏呢。答案以下:app
<?php class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(); } } /** * 後臺基類 * Class Backend_Controller */ class Backend_Controller extends MY_Controller { public function __construct() { parent::__construct(); } } /** * 前臺基類 * Class Frontend_Controller */ class Frontend_Controller extends MY_Controller { public function __construct() { parent::__construct(); } }
不指定任何控制器時,但願可以訪問默認控制器,因此咱們去設置$route['default_controller'] = 'frontend/XXX';可是訪問會提示404錯誤,究竟是由於什麼緣由呢。
查看system/core/Router.php源碼frontend
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; }
關鍵在於定義MY_Router類,重寫_set_default_controller方法this
<?php class MY_Router extends CI_Router { 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(sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2) { $method = 'index'; } if(is_dir(APPPATH.'controllers/'.$class)) { $this->set_directory($class); $class = $method; if (sscanf($method, '%[^/]/%s', $class, $method) !== 2) { $method = 'index'; } } if(!file_exists(APPPATH . 'controllers/' . $this->directory.ucfirst($class) . '.php')) { return; } $this->set_class($class); $this->set_method($method); $this->uri->rsegments = [ 1 => $class, 2 => $method ]; } }
Demo地址設計