Typecho 代码阅读笔记(二) - 数据库访问

Typecho 代码阅读笔记(三) - 插件机制
Typecho 代码阅读笔记(二) - 数据库访问
Typecho 代码阅读笔记(一) - 页面渲染及路由机制

转载请注明出处:http://blog.csdn.net/jh_zzz

 

这一块比较复杂,我还没有完全理解为什么要把 SQL 语句的组装搞这么复杂。

从一个普通皮肤页面开始 themes/default/index.php ,代码如下:

<?php while ($this -> next()): ?>

    < div class ="post">

       < h2 class ="entry_title">< a href ="<?php $this -> permalink() ?>"><?php $this -> title() ?></ a ></ h2 >

       < p class ="entry_data">

           < span ><?php _e(' 作者: ' ); ?><?php $this -> author(); ?></ span >

           < span ><?php _e(' 发布时间: ' ); ?><?php $this -> date('F j, Y' ); ?></ span >

           < span ><?php _e(' 分类: ' ); ?><?php $this -> category(',' ); ?></ span >

           < a href ="<?php $this -> permalink() ?>#comments"><?php $this -> commentsNum('No Comments' , '1 Comment' , '%d Comments' ); ?></ a >

       </ p >

       <?php $this -> content(' 阅读剩余部分 ...' ); ?>

    </ div >

<?php endwhile ; ?>

 

从上面我们知道这个文件是在 Widget_Archive 执行时被 包含进来的,所以在这里 $this 就是 Widget_Archive next() 函数具体实现在 Typecho_Widget 中,他只是从 $stack 中取出一行数据返回,然后移向下一行, $stack 中的数据是如何生成的呢?

 

Widget_Archive execute 函数中,有这几行:

$select = $this -> select()-> where ('table.contents.status = ?' , 'publish' )

-> where('table.contents.created < ?' , $this -> options-> gmtTime);

中间代码略过

$select -> order('table.contents.created' , Typecho_Db:: SORT_DESC)

-> page($this -> _currentPage, $this -> parameter-> pageSize);

$this -> db-> fetchAll ($select , array ($this , 'push' ));

 

下面是 Widget_Abstract_Contents:: select() 函数的具体实现:

return $this -> db-> select ('table.contents.cid' , 'table.contents.title' , 'table.contents.slug' , 'table.contents.created' , 'table.contents.authorId' ,

'table.contents.modified' , 'table.contents.type' , 'table.contents.status' , 'table.contents.text' , 'table.contents.commentsNum' , 'table.contents.order' ,

'table.contents.template' , 'table.contents.password' , 'table.contents.allowComment' , 'table.contents.allowPing' , 'table.contents.allowFeed' ,

'table.contents.parent' )-> from ('table.contents' );

$this->db Typecho_Db 对象,是 Widget_Abstract 初始化时赋值的:

$this -> db = Typecho_Db:: get();

这个值其实是在 config.inc.php 中创建的,在安装的时候根据用户选择生成的:

$db = new Typecho_Db('Mysql' , 'typecho_' );

中间略过

Typecho_Db:: set($db );

 

再看看 Typecho_Db select() 函数,

return call_user_func_array(array ($this -> sql() , 'select' ), $args ? $args : array ('*' ));

$this->sql() 返回一个 Typecho_Db_Query 对象,所以上面这句是调用 Typecho_Db_Query select 函数并将相应的参数传给它, Typecho_Db_Query 会经过一系列的处理最终生成 SQL 语句,这里不再具体看了。

 

看看生成好的语句是怎么执行的,在最前面提到有这句代码:

$this -> db-> fetchAll($select , array ($this , 'push' ));

Typecho_Db fetchAll 具体实现如下:

public function fetchAll($query , array $filter = NULL )

{

    // 执行查询

    $resource = $this -> query ($query , self:: READ);

    $result = array ();

   

    /** 取出过滤器 */

    if (! empty ($filter )) {

        list ($object , $method ) = $filter ;

    }

 

    // 取出每一行

    while ($rows = $this -> _adapter-> fetch ($resource )) {

        // 判断是否有过滤器

        $result [] = $filter ? call_user_func (array (& $object , $method ), $rows ) : $rows ;

    }

 

    return $result ;

}

 

首先执行 query() query() 函数会执行:

$resource = $this -> _adapter-> query($query , $handle , $op , $action );

然后将查询的结果返回,根据上面提到的 config.inc.php ,这里的 _adapter Typecho_Db_Adapter_Mysql ,他其实就是执行了一个 mysql 查询:

if ($resource = @ mysql_query($query instanceof Typecho_Db_Query ? $query -> __toString() : $query , $handle )) {

    return $resource ;

}

这里的 $query->__toString() 会返回经过 Typecho_Db_Query 处理后的 最终用来执行的 SQL 语句。

得到查询结果后,上面的 fetchAll 函数就循环调用回调函数将数据回调出去,前面的代码中 Widget_Archive 在调用时指定的是 push ,在 push 函数中返回的每一行数据都被压入 $stack ,这样 $stack 中就有了一行行的数据了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值