评论

收藏

[PHP] ThinkPHP源码阅读3------行为扩展

开发技术 开发技术 发布于:2021-06-22 18:52 | 阅读数:507 | 评论:0

  ThinkPHP的核心采用的框架模式是CBD,也就是核心Core+行为Behavior+驱动Driver,核心也就是整个框架模式的核心,大部分都是一些基类,去规定规则,Behavior是行为,就是在指定的地方调用来完成一些特定的行为功能,而Driver驱动就类似cache缓存驱动,mysqldb 数据库驱动等,完成功能
  行为在手册的13.1中说的很详细.我只去写一些实例.调用行为的方法.
  调用方法是tags()
/**
 * 处理标签扩展
 * @param string $tag
 *      标签名称
 * @param mixed $params
 *      传入参数
 * @return mixed
 */
function tag($tag, &$params = NULL) {
  // 系统标签扩展
  $extends = C ( 'extends.' . $tag );
  // 应用标签扩展
  $tags = C ( 'tags.' . $tag );
  if (! empty ( $tags )) {
    if (empty ( $tags ['_overlay'] ) && ! empty ( $extends )) { // 合并扩展
      //array_unique   移除数组中重复的值
      $tags = array_unique ( array_merge ( $extends, $tags ) );
    } elseif (isset ( $tags ['_overlay'] )) { // 通过设置 '_overlay'=>1 覆盖系统标签
      unset ( $tags ['_overlay'] );
    }
  } elseif (! empty ( $extends )) {
    $tags = $extends;
  }
  if ($tags) {
    if (APP_DEBUG) {
      G ( $tag . 'Start' );
      trace ( '[ ' . $tag . ' ] --START--', '', 'INFO' );
    }
    // 执行扩展
    foreach ( $tags as $key => $name ) {
      if (! is_int ( $key )) { // 指定行为类的完整路径 用于模式扩展
        $name = $key;
      }
      B ( $name, $params );
    }
    if (APP_DEBUG) { // 记录行为的执行日志
      trace ( '[ ' . $tag . ' ] --END-- [ RunTime:' . G ( $tag . 'Start', $tag . 'End', 6 ) . 's ]', '', 'INFO' );
    }
  } else { // 未执行任何行为 返回false
    return false;
  }
}
  tag调用的时候,可以指定覆盖系统行为.之后会调用B函数去实例化行为对象.
/**
 * 执行某个行为
 *
 * @param string $name
 *      行为名称
 * @param Mixed $params
 *      传入的参数
 * @return void
 */
function B($name, &$params = NULL) {
  if (strpos ( $name, '/' )) {
    list ( $name, $method ) = explode ( '/', $name );
  } else {
    $method = 'run';
  }
  $class = $name . 'Behavior';
  if (APP_DEBUG) {
    G ( 'behaviorStart' );
  }
  $behavior = new $class ();
  $behavior->$method ( $params );
  if (APP_DEBUG) { // 记录行为的执行日志
    G ( 'behaviorEnd' );
    trace ( $name . ' Behavior ::' . $method . ' [ RunTime:' . G ( 'behaviorStart', 'behaviorEnd', 6 ) . 's ]', '', 'INFO' );
  }
}
  B函数可以实例化行为对象,并且传入行为需要的参数.行为需要的参数可以在配置文件config.php中更改.并且会覆盖行为中的默认参数.
  行为的基类在Lib/Conf/Behavior.class.php中
  protected $options =  array(); 保存行为的参数
  __construct    初始化类,参数赋值.   主要就是赋值,如果在config.php中存在的话,就用config.php中得覆盖.
  __get          获取参数     获取行为参数
  run             行为唯一执行入口
  在B函数中,也可以手动指定参数执行入口,方法是B('类名/方法名')的方式
  默认的行为有:

CheckRoute检测路由,路由匹配
ContentReplace模板内容输出替换
ParseTemplate模板解析
ReadHtmlCache静态缓存读取
ShowPageTrace页面Trace显示
ShowRuntime运行时间显示
TokenBuild表单令牌生成
WriteHtml静态缓存写入
  扩展行为有

AgentCheck代理检测
BrowserCheck浏览器检测,防刷新
CheckActionRoute操作路由检测
CheckLang语言检测,并且自动加载语言包
CronRun自动任务
FireShowPageTrace将Trace输出到firefox的firebug
RobotCheck机器人检测(就是检测百度蜘蛛等)
Upgrade自动升级提示行为
  现在写一个例子,大家就可以理解了.
  在App.class.php中,App::run的方法里,有一个调用应用初始化标签的地方.
/**
   * 运行应用实例 入口文件使用的快捷方法
   * @access public
   * @return void
   */
  static public function run() {
    // 项目初始化标签
    tag('app_init');
    App::init();
    // 项目开始标签
    tag('app_begin');
    // Session初始化
    session(C('SESSION_OPTIONS'));
    // 记录应用初始化时间
    G('initTime');
    App::exec();
    // 项目结束标签
    tag('app_end');
    return ;
  }
  现在在项目/Lib/Behavior里新建一个AppinitBehavior.class.php
<?php
class AppinitBehavior extends Behavior{
  function run(&$param){
    echo '应用开始了';
  }
}
  然后在项目/Conf/tags.php里
<?php
return array(
  'app_init'=>array(
    'Appinit'
  )
);
  这样,在运行项目的时候,则会都输出应用开始了.非常方便.如果要修改,扩展,都直接修改类或者扩展类即可,不需要修改源代码,扩展性非常好.
DSC0000.jpg   


  
关注下面的标签,发现更多相似文章