CI钩子

最近研究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什么的就不用再单独定义,新写的东西肯定有问题,但是原理绝对没问题,所以明白原理是最重要。

代码有些多,但是非常有必要仔细看一下
这些代码都是本主题用到的代码,其他不相关的代码都清除了
这只是基本实现,欢迎提出建议和意见

 

 

 

 

  

 

 

 

 

 

经过进一步修改基本可以应用到实际

PHP

 
/libraries/X_Controller.php
<?php
class
X_Controller extends Controller{
      //默认布局文件
       var $layout= 'layouts/layout.php';
      var $data=array();
       public function X_Controller(){
             parent::Controller();
              $this->validate();
              $this->load->scaffolding('');
       }
      
       //登录验证
       protected function validate(){
             //如果要显示登录窗口就不进行有效性验证
              if(strpos(uri_string(),'ares/login')!=FALSE){
              //验证系统管理员
              }elseif(strpos(uri_string(),'ares')!= FALSE){
                    if($this->session->userdata ( 'admin_logged' ) =='yes'){
                    }else{
                          redirect('ares/login');
                    }
             }
       }
}
 
controllers/start.php

class Startextends X_Controller {
 
       function Start()
      {
             parent::X_Controller();
       }
      
       function index()
      {
             $this->data['title']='这里是标题';
             $this->data['test']='测试一下';
      }
}
 
 
config/hooks.php
$hook['post_controller'][] =array(
                          'class'   => 'Layout',
                          'function' => 'render',
                          'filename' => 'Layout.php',
                          'filepath' => 'hooks',
                          'params'  => array()
                          );
 
hooks/Layout.php
<?php
class
Layout{
      var $CI;
      var $layout;
      var $content;
      var $data= array();
 
       function Layout(){
             $this->CI=&get_instance();
              //从控制器中读取layout
             $this->layout=$this->CI->layout;
             //从控制器读取数据
              $this->data=$this->CI->data;
             //确定目标视图
              $this->content=$this->CI->router->directory.$this->CI->router->class.'/'.$this->CI->router->method;
      }
      
       function render(){
             //初始化目标视图
              $this->data['content']=$this->CI->parser->parse($this->content,$this->data,TRUE);
              $this->append_title();
             
              $this->CI->parser->parse($this->layout,$this->data);
       }
       private function append_title(){
             $this->data['title'].=$this->CI->config->item('title_suffix');
       }
}
 
views/layouts/layout.php
<!DOCTYPE htmlPUBLIC "-//W3C//DTD XHTML1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<base href="<?php echo $this->config->item('base_url');?>"/>
<meta http-equiv="Content-Type" content="text/html;charset=<?php echo $this->config->item('charset');?>"/>
<meta name="author"content="" />
<meta name="keywords"content="" />
<meta name="description" content=""/>
<link rel=stylesheet href="dcss/common.css" type="text/css">
<title>{title}</title>
</head>
<body>
<div id="header">
      <tablewidth="100%">
             <tr>
                    <td width="74%"><h1>codehere.net</h1></td>
                    <tdwidth="26%">登录注册</td>
             </tr>
      </table>
      <ulid="nav">
             <li><ahref="#">首页</a></li>
       </ul>
      <divclass="clear_left"></div>
</div>
<div id="content">
{content}<br />
</div>
<div id="footer">
#footer
</div>
</body>
</html>
 
视图 views/start/index.php

{test}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值