wordpress pingback与trackback分析

以下关于pingback与trackback的内容摘自:
WordPress中的Trackback和Pingback | 只言片语

PingBack与TrackBack的工作流程

PingBack与TrackBack的目标在于简化多个博客间相关内容的关联过程。让我们设想一下,没有PingBack与TrackBack时的情况:

博客A发布了一篇文章;
博客B看到后,发布评论、引用、介绍博客A上该篇文章的贴子;
但此时博客A是无从知道博客B上对自己文章的引用情况的,要让博客A知道,博客B须:
在博客A上留言,介绍自己对该篇文章的看法,比如说“在我的博客发布了一篇文章,也讨论这个问题——”,并附上相应页面的链接;
向博客A发送E-mail,说明自己对该篇文章的进一步讨论,同时,也许希望博客A能在页面上放上自己的链接,以帮助对这一话题有兴趣的用户能找到自己的博客;
PingBack与TrackBack实现的功能便是将第三个步骤自动化了,再也不需这么一个繁琐的过程,即:

博客A发布了一篇文章;
博客B看到后,发布评论、引用、介绍博客A上该篇文章的贴子;
在文章发布时,博客B即自动向博客A发送Pingback或TrackBack;
博客A收到相应的Pingback或TrackBack,如果未设置人工审核,相应的内容即会出现在博客A该文的留言中,如果设置了人工审核,则出现在博客A的审核列表中,俟博客A认为不是spam后将其发布在留言中。

首先看wp-includes/default-filters.php 第236行:

1
add_action( 'do_pings',                   'do_all_pings',            10, 1 );

这里给do_pings hook 添加了 do_all_pings这个action .
default-filters.php 第247行:

1
add_action( 'publish_post',               '_publish_post_hook',       5, 1 );

这里给publish_post hook 添加了_publish_post_hook 这个action.
publish_post这个动作是在文章发布时触发的。
然后我们看下_publish_post_hook 这个action干了些什么:
在wp-includes/post.php 第4493行,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 /**
 * Hook to schedule pings and enclosures when a post is published.
 *
 * @since 2.3.0
 * @access private
 * @uses $wpdb
 * @uses XMLRPC_REQUEST and APP_REQUEST constants.
 * @uses do_action() Calls 'xmlprc_publish_post' on post ID if XMLRPC_REQUEST is defined.
 * @uses do_action() Calls 'app_publish_post' on post ID if APP_REQUEST is defined.
 *
 * @param int $post_id The ID in the database table of the post being published
 */

function _publish_post_hook($post_id) {
    global $wpdb;

    if ( defined('XMLRPC_REQUEST') )
        do_action('xmlrpc_publish_post', $post_id);
    if ( defined('APP_REQUEST') )
        do_action('app_publish_post', $post_id);

    if ( defined('WP_IMPORTING') )
        return;

    $data = array( 'post_id' => $post_id, 'meta_value' => '1' )
        //若后台”评论选项“中的“尝试通知文章中链接到的所有博客”为勾选的,
    //则插入此post的meta '_pingme'和'_encloseme',其post_id 为文章id,meta值为1
    //这个实际上是起到标记的作用
   
    if ( get_option('default_pingback_flag') ) {
        $wpdb->insert( $wpdb->postmeta, $data + array( 'meta_key' => '_pingme' ) );
        do_action( 'added_postmeta', $wpdb->insert_id, $post_id, '_pingme', 1 );
    }
    $wpdb->insert( $wpdb->postmeta, $data + array( 'meta_key' => '_encloseme' ) );
    do_action( 'added_postmeta', $wpdb->insert_id, $post_id, '_encloseme', 1 );
//注册调度任务
    wp_schedule_single_event(time(), 'do_pings');
}

wp_schedule_single_event 将在超过时间后触发指定的hook(这里是do_pings)一次,
同一个事件在10分钟内只会触发一次,详见:
Function Reference/wp schedule single event « WordPress Codex

comment.php 第1646行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/**
 * Perform all pingbacks, enclosures, trackbacks, and send to pingback services.
 *
 * @since 2.1.0
 * @uses $wpdb
 */

function do_all_pings() {
    global $wpdb;

    // Do pingbacks
    //从库中取出_pingme meta ,得到其meta_id ,并删除之
    //这些存在于postmeta表中的_pingme 都是未ping的post的。
    while ($ping = $wpdb->get_row("SELECT * FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_pingme' LIMIT 1")) {
    //如果还有未ping的post,先删除其_pingme meta
        $mid = $wpdb->get_var( "SELECT meta_id FROM {$wpdb->postmeta} WHERE post_id = {$ping->ID} AND meta_key = '_pingme' LIMIT 1");
        do_action( 'delete_postmeta', $mid );
        //执行删除操作,从库中删除之
        $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE meta_id = %d", $mid ) );
        do_action( 'deleted_postmeta', $mid );
        //自动ping 博文中引用的链接
        pingback($ping->post_content, $ping->ID);
    }

    // Do Enclosures
    while ($enclosure = $wpdb->get_row("SELECT * FROM {$wpdb->posts}, {$wpdb->postmeta} WHERE {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id AND {$wpdb->postmeta}.meta_key = '_encloseme' LIMIT 1")) {
        $mid = $wpdb->get_var( $wpdb->prepare("SELECT meta_id FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key = '_encloseme'", $enclosure->ID) );
        do_action( 'delete_postmeta', $mid );
        $wpdb->query( $wpdb->prepare("DELETE FROM {$wpdb->postmeta} WHERE meta_id =  %d", $mid) );
        do_action( 'deleted_postmeta', $mid );
        //检查视频音频链接的内容,将内容作为enclosures加入。
        //已经添加的enclosure将不再重新加入。
        //它实际上干的事情就是:
        //检查post中所有链接,若连接指向的资源是video或者audio ,则
        //为该post创建一个名为enclosure的meta_key,其meta_value为url\n
        //资源大小\n资源的MIME类型
        //有关RSS enclosures 见下面的说明。
        do_enclose($enclosure->post_content, $enclosure->ID);
    }

    // Do Trackbacks
    //这里是处理trackback的,to_ping就是
    //你在后台发布日志时手动填写的trackback地址
    /*
    对于每一篇已经发布的文章,对其do_trackbacks
    do_trackbacks干什么了呢?see wp-includes/comment.php line 1683
    取得文章的to_ping ,也就是要ping 的trackbacks,然后发送trackback,
    发送的内容包括文章标题,内容截取(252个字节加上...)
    ping 完之后,更新数据表中的数据,把每个已经ping 过的trackback地址替换为
    空。(一篇文章可能有多个trackback,因此那里$to_ping是个数组)
    */

    $trackbacks = $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE to_ping <> '' AND post_status = 'publish'");
    if ( is_array($trackbacks) )
        foreach ( $trackbacks as $trackback )
            do_trackbacks($trackback);

    //Do Update Services/Generic Pings
    //这里的generic_ping,从库中取出ping服务器urls(即我们在后台”撰写“-》”更新服务器“ 里面填写的东东。
    //如果不想通知更新服务,可以在administration管理界面的选项->撰写中删除“更新服务”中的内容。
    /*
    更新服务是一种让别人知道你的博客有更新的工具。在你每次创建或者更新博客时通过XML-RPC ping会让WP自动的通知给一些流行的更新服务商(如Technorati,Sphere,rssfeeds这些内容聚合网站)。相应的更新服务商会处理ping并更新他们的索引。这样别人再浏览更新服务商网站时便能看到你的博客更新。
    */

    generic_ping();
}

因此,wp实际上有三种方式的ping:

自动ping (pingback)
”手动“ping (trackback)
generic ping

PS:
关于RSS enclosure From Wikipedia:

RSS enclosure

RSS enclosures are a way of attaching multimedia content to RSS feeds by providing the URL of a file associated with an entry, such as an MP3 file to a music recommendation or a photo to a diary entry. Unlike e-mail attachments, enclosures are merely hyperlinks to files, the actual file data is not embedded into the feed (unless a data URL is used). Support and implementation among aggregators varies: if the software understands the specified file format, it may automatically download and display the content, otherwise provide a link to it or silently ignore it.

The addition of enclosures to RSS, as first implemented by Dave Winer in late 2000 [1], was an important prerequisite for the emergence of podcasting, arguably the most common use of the feature as of 2010. In podcasts and related technologies enclosures are not merely attachments to entries, but provide the main content of a feed.

更多
No Responses Post a comment

Leave a Reply

Note: You may use basic HTML in your comments. Your email address will not be published.

Subscribe to this comment feed via RSS