讓 WP2.0 可以正常trackback

An english version of this post can be found here .

把站台從 wordpress 1.5 升上 wordpress 2.0 的人們,可能發現不能 Trackback了。我,也中標了。

Ah Knight’s Blog提供了一個蠻暴力的解法變通的方法:把資料庫中的 to_ping欄位給清光光,並提及可能的原因是:

this problem is because of to_ping field contain some char ( including space, tab which represent by \n\r )

正好在 IRC 上,我跟 ijliaopriv也在討論這個問題,既然問題可能出在 to_ping這個欄位,於是乾脆進source裡翻翻看,看問題到底出在哪裡。

不翻則已,一翻嚇出一聲冷汗。

WordPress 1.5以前發表文章要送出時,使用者得先等 trackback/ping 別人的動作完成。當有許多的URL要trackback時,一個個tackback的結果是換來使用者的漫長等待。因此,在 WordPress 2.0以後,改用了另外一種方式以減少文章按下「發表」之後的等待。其作法是另外用fsockopen呼叫另一個 script來作trackback的動作:wp-admin/execute-pings.php

問題就出在這個 wp-admin/execute-pings.php 裡。

在 wp-admin/execute-pings.php 中,trackback的部份是這樣子實作的:


// Do Trackbacks
while ($trackback = $wpdb->get_row("SELECT ID FROM $wpdb->posts WHERE TRIM(to_ping) != '' AND post_status != 'draft' LIMIT 1")) {
    echo "Trackback : $trackback->ID";
    do_trackbacks($trackback->ID);
} ?>

正常情況下,程式去讀出資料庫中第一筆需要trackback 的post,做完 do_trackbacks,然後以此類推,直到最後一筆做完為止。但是有沒有發現到,萬一第一筆(or第 n筆)沒有trackback成功,仍然留在資料庫中時,會發生什麼事?

是的,用 while這個寫法會使得程式一直嘗試對第一筆符合的資料做 trackback 動作,永遠不會停下來。(這就是我討厭 while的地方)

於是程式永遠在跑第一筆,當然不可能跑到最後一筆(就是要送出 trackback 的那一筆),於是乎,trackback就沒有送出去。

那麼,又是什麼原因為讓之前沒送成功的trackback再次失敗呢?

第一種情況:對方的網頁根本就關掉 trackback了,或是要trackback的網址已經不存在了。那麼trackback當然會失敗。

第二種情況:在 wp-includes/function-post.php 的 do_trackbacks()裡,要先呼叫 wp-includes/function-post.php 的 get_to_ping() 把當要trackback的網址(to_ping)切成array,但是當 to_ping 只剩下一些怪怪的值,如 “\n”(換行)符號,會被下面這一行濾掉:

$to_ping = preg_split('/\s/', $to_ping, -1, PREG_SPLIT_NO_EMPTY);

於是傳回的array變empty array,再碰上 do_trackbacks()裡的這一行:


if ( empty($to_ping) )
return;

噹噹! 就什麼也不做地走掉了,然後回去又碰到 while,就是永無止盡的無窮迴圈了。


解決辦法:在 WP 出新版/新patch解決這個問題之前,可以試試自己改source:

PS. 這只是頭痛醫頭,pingback 也有同樣的問題,不過我不管他了。XD

wp-includes/function-post.php line 700:


if ( empty($to_ping) )
return;

改成


if ( empty($to_ping) ) {
    $wpdb->query("UPDATE $wpdb->posts SET to_ping = '' WHERE ID ='$post_id'");
    return;
}

wp-admin/execute-pings.php line 21:


// Do Trackbacks
while ($trackback = $wpdb->get_row("SELECT ID FROM $wpdb->posts WHERE TRIM(to_ping) != '' AND post_status != 'draft' LIMIT 1")) {
  echo "Trackback : $trackback->ID";
  do_trackbacks($trackback->ID);
}

改成


// Do Trackbacks
// The old code will cause infinite loop when trackback failed.
//

$trackbacks = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE TRIM(to_ping) != '' AND post_status != 'draft'");

if (is_array($trackbacks) && count($trackbacks)) {
    foreach ($trackbacks AS $trackback  ) {
        echo "Trackback : $trackback->ID";
        do_trackbacks($trackback->ID);

    } // end foreach

}

或是直接下載 patch檔 解開後,放到要patch的檔案目錄下。在命令列下用 patch 指令(如果有的話):


patch functions-post.php functions-post.php.diff
patch execute-pings.php execute-pings.php.diff

在〈讓 WP2.0 可以正常trackback〉中有 43 則留言

  1. 自動引用通知: Blogging Pro China » Blog Archive » 讓 WP2.0 可以正常trackback
  2. 好樣 ..! 可是我滿反對改source …
    還有堅決反對把我的方法叫做 ‘暴力的解法’
    我覺得我的方式是用來過濾to_ping~~~~~

  3. Knight:
    我也不喜歡改source 🙂
    用清欄位的方法過陣子還是會出問題。

    可惜不能用plugin實作。

    最好的方式還是讓官方release修正版本。

  4. 自動引用通知: maTT cHEn {dot} info » WordPress 2.0 的引用?
  5. 自動引用通知: SOLiDrAiNbOw Scroll » Marks-Digg for 2005-12-30
  6. 自動引用通知: fireyy blog
  7. 自動引用通知: 抓~ 抓到一隻瞌睡蟲
  8. 自動引用通知: 抓~ 抓到一隻瞌睡蟲 » Blog Archive » wp 2.0 ping不出去
  9. 唉,不知利用了多少方法,都不成功。有谁可以来一个详细的教程。
    把資料庫中的 to_ping欄位給清光光?这是说把里面的内容清光光还是把该表删掉。两种方法我都试了,内容清光光,那之前发的贴子出现一个框框,里面全是代码。将该表删掉,不能发贴。。。。。。。

    有谁解决了这个问题,请给我一个方法,可以吗?

  10. 用 PipperL 這篇文章介紹的改 WordPress 程式碼的方法比較安全吧,資料庫的內容最好不要隨便亂碰,可能會有意想不到的副作用。

    PipperL 所提的修改方法,已經被 WordPress 官方採納,列入 changeset #3384。如果你不熟悉 patch 的使用法,不妨去上述地點下載更正過的 wp-includes/functions-post.php 及 wp-admin/execute-pings.php 檔。

  11. 自動引用通知: My Blog,My Feeling » 把 WP 升成 2.0
  12. 自動引用通知: 與飛隨筆
  13. 自動引用通知: Human World Like A Dream » [WP]升級至2.0正式版VS.版面與留言板更新
  14. 自動引用通知: 終極邊疆BLOG
  15. 自動引用通知: HEMiDEMi
  16. 自動引用通知: 無聊人的無聊故事 » 幾個軟體更新
  17. 自動引用通知: 阿辛的Blog
  18. 自動引用通知: Human World Like A Dream
  19. 自動引用通知: Lakers部落手記 » WP2.0 Trackback問題
  20. 自動引用通知: hsuyo BLOG
  21. 自動引用通知: hsuyo BLOG
  22. 自動引用通知: 简单 - 没辙了,ping不出去
  23. 自動引用通知: 么什山人 » Blog Archive » 就这点破事,害得我乱七八糟
  24. 自動引用通知: 凭栏独品» Blog Archive » 就这点破事,害得我乱七八糟

留言功能已關閉。