关于wordpress的$post全局变量,以及主循环the loop的一些个人理解。

 

这两天在做自己的网站博客的时候,在修改主题的时候遇到了一些$post全局变量的问题。现在做点记录。

===================================================================================

http://codex.wordpress.org/Global_Variables

这里是wp官方的全局变量列表。里面涉及到了所有的wp全局变量,但是大部分没有具体的解释。

=================================================================================== 

$post的一些成员属性,可以参考这个网址:http://codex.wordpress.org/Function_Reference/get_post

get_post()函数返回的值可以是object/Array。

===================================================================================

网上关于主循环the loop和全局变量的说明。

http://fairyfish.net/2007/07/07/global-variables-and-the-wordpress-loop/

其中提到:

the_post() 函数被调用之后,你就可以使用许多模板函数和全局变量。

以及:

全局变量 post,你可以使用以下代码调用它:

global $post;
echo $post->post_title;

通过post这个全局变量还可以让你获取:ID,post_author,post_date,post_excerpt,comment_count 和其他。

按照作者的意思来讲,此$post变量只有在主循环之中才可以被调用,也就是说在the_post()函数被调用之前,该变量是没有被赋值的。

可是,现实往往是和人的理想相违背的。我们经常可以看到一些wp模板教程中提到使用$post->xxx来获取很多内容,包括title,content等等。

而往往这些调用却放在了主循环之外。最典型的例子就是关于如何设置wordpress的<meta>标签:

http://www.chinaz.com/web/2011/0605/186189.shtml

其中调用到了$post->post_content,$post->post_excerpt等等内容,且这段代码都是放在header.php的模板文件中的,众所周知the_post()等函数都是在get_header()函数之后的。

===================================================================================

这样的话,是不是很矛盾?

看到这里,我心里的一种声音强烈的呼唤要把这个矛盾解开。

===================================================================================

我开始在wp的源代码中进行不断的搜索……

首先,我在class-wp.php文件中看到了这些代码:

function register_globals() {
     global  $wp_query;
     //  Extract updated query vars back into global namespace.
     foreach ( ( array$wp_query->query_vars  as  $key =>  $value) {
         $GLOBALS[ $key] =  $value;
    }

     $GLOBALS['query_string'] =  $this->query_string;
     $GLOBALS['posts'] = &  $wp_query->posts;
     $GLOBALS['post'] = ( isset( $wp_query->post)) ?  $wp_query->post :  null;
     $GLOBALS['request'] =  $wp_query->request;

     if ( is_single() || is_page() ) {
         $GLOBALS['more'] = 1;
         $GLOBALS['single'] = 1;
    }
}

所以,这里可以说明$post和一些类似的全局变量是属于wp_query这个对象的。

我在query.php这个文件中又找到了wp_query对象的定义:

  function &query_posts( $query) {
     unset( $GLOBALS['wp_query']);
     $GLOBALS['wp_query'] =&  new WP_Query();
     return  $GLOBALS['wp_query']->query( $query);
}

接下去,不用说,让我们看看WP_Query的一些类成员和函数吧:

class WP_Query {
     // ...
     var  $posts;
     var  $post;
     // ...
     function the_post() {
         global  $post;
         $this->in_the_loop =  true;

         if (  $this->current_post == -1 )  //  loop has just started
            do_action_ref_array('loop_start',  array(& $this));

         $post =  $this->next_post();
        setup_postdata( $post);
    }
     // ...
     function next_post() {

         $this->current_post++;

         $this->post =  $this->posts[ $this->current_post];
         return  $this->post;
    }
     // ...
}
function the_post() {
     global  $wp_query;

     $wp_query->the_post();
}

function have_posts() {
     global  $wp_query;

     return  $wp_query->have_posts();
}

这里我们可以很清楚的看到$post的赋值了,显然$post是属于$posts数组中的一个。

而the loop中的函数也是调用的$wp_query的成员函数,显然,the_post()和$post他们都是来自同一个对象的。

这样说来,也就是当这个对象被创建的时候,他们二者已经同时存在了。

在我继续搜索"post ="这个字符串来确定他的赋值问题的时候,发现,在整个wp中,出现了几十次的赋值,也就是说$post经常被实行赋值的运算。

虽然这样不能完全证明在the loop之前,$post就已经被赋值,但是至少可以证明,不仅仅只有the loop中的the_post()函数才可以给$post赋值。

我们有理由相信,$post在页面还没有刷出,或者说程序还没有进入主循环的时候,就已经被赋值了。 

===========================================================

由于wp程序的博大精深以及我个人的才疏学浅,始终无法完全解释这个矛盾。

至此,虽心中有万般不甘,也只好暂时放弃。

 

 

至于$post是如何被做为一个对象(因为有$post->ID,证明$post是一个对象)赋值的,本人也只能找到一些相关的线索,始终无法诠释。

在此略微记录:

我们知道$post其实就是$posts数组中的一个,所以我从$posts入手,找到了位于query.php文件中的get_posts()函数,其中我发现了一些赋值语句。

包括:

function &get_posts() {
     // ...
     $this->posts =  $wpdb->get_col( $this->request);
     // ...
     $this->posts =  $wpdb->get_results( $this->request);    
     // ...
     $this->posts = apply_filters_ref_array('the_posts',  array$this->posts, & $this ) );
     // ...
     if (  $this->post_count > 0 ) {
         $this->post =  $this->posts[0];
    }
     // ...
}

 

我们可以肯定的是$posts的赋值肯定要追溯到wp-db.php中的db类(废话,呵呵),以及一些奇奇怪怪的函数。(也许解开这个谜团的同时,也能解开我前面提到的矛盾)

还有post.php中的function &get_post(&$post, $output = OBJECT, $filter = 'raw') 中可能讲到了该对象的构建(没有深入去看)。

到这里,我不得不再次感叹wp的博大精深,以及鄙视我自己“小人之心度君子之腹”的行为。

 

到此,这篇日志结束。

不知道我心中的这些疑惑何时能解开或者说能不能解开。

希望有到此处的同学,如果你能为我解惑,请务必指明道路,在下感激不尽。

你可能感兴趣的:(String,filter,wordpress,header,query,variables)