最近研究CI的Session无意中发现CI的钩子非常强劲和灵活。 之前学习ZendFramework感觉嵌入视图非常不错,今天就用CI的钩子实现一个 准备工作,个人建议最好看一下CI的大体运行流程,打开config.php修改$config['log_threshold']= 2;这样在system/logs生成记录debug信息的日志文件,打开一个页面,日志文件如下(如果没有生成日志文件,尝试修改$config['base_url']为正确的值): DEBUG - 2010-03-12 02:10:23 --> Config ClassInitialized DEBUG - 2010-03-12 02:10:23 --> Hooks ClassInitialized DEBUG - 2010-03-12 02:10:23 --> URI ClassInitialized DEBUG - 2010-03-12 02:10:23 --> No URI present.Default controller set. DEBUG - 2010-03-12 02:10:23 --> Router ClassInitialized DEBUG - 2010-03-12 02:10:23 --> Output ClassInitialized DEBUG - 2010-03-12 02:10:23 --> Input ClassInitialized DEBUG - 2010-03-12 02:10:23 --> Global POST andCOOKIE data sanitized DEBUG - 2010-03-12 02:10:23 --> Language ClassInitialized DEBUG - 2010-03-12 02:10:23 --> Loader ClassInitialized DEBUG - 2010-03-12 02:10:23 --> Controller ClassInitialized DEBUG - 2010-03-12 02:10:23 --> Session ClassInitialized DEBUG - 2010-03-12 02:10:23 --> Helper loaded:string_helper DEBUG - 2010-03-12 02:10:23 --> Session routinessuccessfully run DEBUG - 2010-03-12 02:10:23 --> File loaded:E:\websites\ci/system/application/views/welcome_message.php DEBUG - 2010-03-12 02:10:23 --> Final output sent tobrowser DEBUG - 2010-03-12 02:10:23 --> Total executiontime: 0.0534 正式开始 1.启用钩子 $config['enable_hooks'] = TRUE; 启用钩子之后还必须注意,本例使用了模板解析类(非常好用的类),在autoload.php中加载了 2.修改application/config/hooks.php,这里定义钩子 PHP $hook['post_controller'][] =array( 'class' => 'Layout', 'function' => 'render', 'filename' => 'Layout.php', 'filepath' => 'hooks', 'params' => array() ); 复制代码 什么意思手册上说的非常清楚,不再解释 3.控制器 在具体钩子代码之前非常有必要说明一下我的控制器 我扩展了原有控制器以实现更多的功能 libraries/X_Controller.php PHP class X_Controller extends Controller{ //默认布局文件 var $layout = 'layouts/layout.php'; //默认视图 var $views=array( 'head'=>'common/head', 'header'=>'common/header', 'content'=>'', 'footer'=>'common/footer' ); //与默认视图匹配的视图数据 var $data=array( 'head'=>array(), 'header'=>array(), 'content'=>array(), 'footer'=>array() ); public function X_Controller(){ parent::Controller(); } } /controllers/start.php <?php class Startextends X_Controller { function Start() { parent::X_Controller(); } function index() { $this->data['title']='这里是标题'; $this->data['test']='测试一下'; } } 复制代码 这里请注意一下,借鉴ZendFramework的layout模式,与start控制器index方法对应的视图是/views/start/index.php /views/start/index.php代码如下 {test} 默认layout /views/layouts/layout.php HTML <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <htmlxmlns="http://www.w3.org/1999/xhtml"> <head> {head} <linkrel=stylesheet href="dcss/common.css" type="text/css"> <title>{title}</title> </head> <body> {header} <divid="content"> {content}<br/> </div> {footer} </body> </html> 复制代码 4.具体的钩子 /hooks/Layout.php PHP <?php class Layout{ var $CI; var $layout= 'layouts/layout'; var $views= array(); var $data= array(); function Layout(){ $this->CI=&get_instance(); } function render(){ //从控制器中读取layout $this->layout=$this->CI->layout; //从控制器读取视图文件 $this->views=$this->CI->views; //覆盖部分默认视图 $this->views['content']=$this->CI->router->directory.$this->CI->router->class.'/'.$this->CI->router->method; //为每个视图文件准备数据 $data=$this->CI->data; //覆盖部分默认数据 $data['content']=$this->CI->data; //从控制器提取layout中用到的直接数据 $this->data['title']=$this->CI->data['title']; //为layout准备数据 foreach($this->views as$key=>$value){ $this->data[$key]=$this->CI->parser->parse($this->views[$key],$data[$key],TRUE); } $this->append_title(); $this->CI->parser->parse($this->layout,$this->data); } //自动为每个页面的title添加一个后缀,比如-CodeIgniter中国开发者社区 private function append_title(){ $this->data['title'].=$this->CI->config->item('title_suffix'); } } 复制代码 原理比较简单,控制器中不用$this->load->view()或$this->parser->parse(),这些会自动完成,控制器中只需要提供数据($this->data)。 这种结构非常有用。 比如有这样一中情况,每个页面除了header,content,footer,还有些页面有左部导航条left 这时候只需要在layout.php中添加上left导航条就OK 其实既然已经有了layout那么这些header和footer什么的就不用再单独定义,新写的东西肯定有问题,但是原理绝对没问题,所以明白原理是最重要。 代码有些多,但是非常有必要仔细看一下 这些代码都是本主题用到的代码,其他不相关的代码都清除了 这只是基本实现,欢迎提出建议和意见 |