讓 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
 

延伸閱讀

文章資訊

 

目前有 43 個迴響

  1. [...] 最後,如果你的 WordPress 2.0 無法正常 trackback 的話,請參考 PipperL〈讓 WP2.0 可以正常trackback〉一文介紹的修改法。 [...]

  2. [...] 這麼說好像已經有點太慢了,不過如果很在意這個問題的人,好像應該先不要從1.5.2升級到2.0。 Update: PipperL己經弄出了一個解法,可以參考這個說明來修改。 引用時請使用此URL [...]

  3. [...]   讓 WP2.0 可以正常trackback,有很多人开始抱怨WP2.0的trackback失效,这篇文章解析了TB失败的原因,同时提供了改进方法。 [...]

  4. Knight says:

    好樣 ..! 可是我滿反對改source …
    還有堅決反對把我的方法叫做 ‘暴力的解法’
    我覺得我的方式是用來過濾to_ping~~~~~

  5. [...] PipperL(升級到 WordPress 2.0, 讓 WP2.0 可以正常trackback) [...]

  6. PipperL says:

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

    可惜不能用plugin實作。

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

  7. [...] 看來是真的不行trackback,看到很多人都在說解決之道,而我看到終極邊疆BLOG的這篇文章的時候,也對於裡頭的迴響討論的內容蠻贊同的,與其自己修補,補了一大堆,乾脆等官方release新的patch出來好了,不然到時候一定會忘了自己動過甚麼手腳! Filed under: Weblog, Network, Computer, Blog, Rumor and Murmuring — Marlboro @ 11:15 am [...]

  8. PipperL says:

    我放了一些其他的格式,包括 zip 檔/patch好的檔案等,要的人可以到英文版那邊下載。

  9. [...] 讓 WP2.0 可以正常trackback (tags: wordpress digest) [...]

  10. 亿城雪 says:

    我的tb不行,但是pb是好的,真奇怪。而且有相当一部分人tb是好的。

  11. [...] via: 終極邊疆 如果你從1.5.2升上來,且升級前在文章的to_ping欄位還留有未ping完的記錄的話,那麼就應該就非常有可能會遇到這個問題。 [...]

  12. [...] 我前面说过 发现 2.0 无法 TB,今天看了看 FD,发现早就有人发现了,而且还给出了 解决方法但这只是个临时的方法,还是等官方发布修正吧 [...]

  13. fireyy blog says:

    测试一下trackback

    我想应该没问题

  14. wp 2.0 ping不出去

    不是網路斷了…
    是因為bug… XD

  15. [...] 參考這篇 讓 WP 2.0 可以正常trackback [...]

  16. william says:

    剛剛去 svn update,發現這份 patch 已經加到官方 codebase 裡了。

  17. PipperL says:

    william:
    看到了,感謝你的通知。

  18. 佐仔 says:

    唉,不知利用了多少方法,都不成功。有谁可以来一个详细的教程。
    把資料庫中的 to_ping欄位給清光光?这是说把里面的内容清光光还是把该表删掉。两种方法我都试了,内容清光光,那之前发的贴子出现一个框框,里面全是代码。将该表删掉,不能发贴。。。。。。。

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

  19. william says:

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

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

  20. [...] trackback issue , i come out by temp solution clean up the to_ping filed and pepperL fixed the code [...]

  21. [...] 讓 WP2.0 可以正常 trackback [...]

  22. 與飛隨筆 says:

    trackback

    今天學到了一筆,終於了解什麼是trackback..

  23. Antonio says:

    如您所说的修改了,不过看似还无法正常trackback

  24. [...] 升级Wordpress2.0以后似乎无法正常trackback,一直以为是对方关闭了trackback,今天问了海豚才知道是Wordpress2.0的一个bug。 [...]

  25. Antonio says:

    就能ping通您的,其他的好像都不通

  26. [...] 本來我之前是用2.0beta版的,趁著改版面的時間就順便升級囉! 升級方法很簡單,請照著hsuyo兄的這一篇文跟著升級吧!“ trackback 發送失敗的問題 ”就採用 PipperL 的解決方法囉~~~ [...]

  27. WordPress 2.0無法 trackback時的簡易檢查

    雖然之前我有針對 WordPress 2.0 無法trackback時,整理了一個簡單的解決方案,不過還是陸陸續續有人反映一樣trackback不出去。
    這些不管是用email,還是直接在迴響裡反映的人,有的是因為直接把…

  28. [...] 雖然之前我有針對 WordPress 2.0 無法trackback時,整理了一個簡單的解決方案,不過還是陸陸續續有人反映一樣trackback不出去。 [...]

  29. [...]     于是问google,很幸运,很多前辈们也遇到类似情况,并给予了解决方案:http://blog.serv.idv.tw/2005/12/29/379/ [...]

  30. HEMiDEMi says:

    HEMiDEMi – 共享書籤

    終極邊疆BLOG » 讓 WP2.0 可以正常trackback

  31. [...] 終極邊疆BLOG提供給官方的解法(讓 WP2.0 可以正常trackback)有被採用,真是可喜可賀。 [...]

  32. wordpress

    阿瑟幅度

  33. 数据恢复 says:

    TB的字符集很是麻烦啊。。

  34. ﹝WP﹞升級至2.0正式版VS.版面與留言板更新

    這兩天有來這兒了的朋友,相信已發現我不停地在改BLOG版面和留言板的版面〈其實也不算改,我只是套用WP現成的Theme,WP就是有這個好處〉,如今總算都改成我滿意的版面了。
    BLOG版面的Theme…

  35. [...] 讓 WP2.0 可以正常trackback (終極邊疆BLOG) [...]

  36. artcrafts says:

    […] 讓 WP2.0 可以正常trackback (終極邊疆BLOG) […]

  37. hsuyo BLOG says:

    Wordpress 2.0 升級完成

    由 wordpress 1.5.2 升級至 wordpress 2.0,步驟一樣很簡單。
    step 0.
    備份檔案、資料庫;關閉所有使用的 plugin;將原本 wordpress 的安裝資料夾清空 or 移至別處。以下檔案可以保留:
    .htaccess
    wp-config.php

  38. hsuyo BLOG says:

    Wordpress 2.0 升級完成…

    由 wordpress 1.5.2 升級至 wordpress 2.0,步驟一樣很簡單。
    step 0.
    備份檔案、資料庫;關閉所有使用的 plugin;將原本 wordpress 的安裝資料夾清空 or 移至別處。以下檔案可以保留:
    .htaccess
    wp-config.php
    ….

  39. [...] 1、用伟大的google搜到这个看似有用的解决办法,但是对照后发现2.0.4的wordpress源码已经照着他的办法改过了。 [...]

  40. 数据恢复 says:

    看来碰到类似问题的可不止我一个啊

  41. [...]     TrackBack是一个很时髦的东西,我想试着使用一下,于是就像以下文章发送了我的TrackBack,但是发现我无法在他的文章下面看到我发过来的TrackBack,背着石头上山的鱼,而别人可以给我发送trackback,这一点让我很纳闷,是不是wordpress出现了问题,于是到google上搜了一下。 发现也有人遇到了和我一样的问题:freeman’s blog但是他也没有找到解决方案。http://blog.serv.idv.tw/> 終極邊疆BLOG上给出了一个解决方案,但是他针对的是wordpress2.0,我使用的版本是wordpress2.0.2,他上面所说的方案好像也没有多少用处,但是为了保险起见,我还是将自己的wp升级到了2.0.4。 然而问题好像依然照旧,我仍然是只能接受而不能发送,郁闷啊!可是后来我又尝试了申请了一个my.donews结果发现可以给这篇文章发送trackback,这是怎么一回事情,虽然tb不是必须,但是我觉得还是挺有用的。 wordpress [...]

  42. [...]     TrackBack是一个很时髦的东西,我想试着使用一下,于是就像以下文章发送了我的TrackBack,但是发现我无法在他的文章下面看到我发过来的TrackBack,背着石头上山的鱼,而别人可以给我发送trackback,这一点让我很纳闷,是不是wordpress出现了问题,于是到google上搜了一下。 发现也有人遇到了和我一样的问题:freeman’s blog但是他也没有找到解决方案。 終極邊疆BLOG上给出了一个解决方案,但是他针对的是wordpress2.0,我使用的版本是wordpress2.0.2,他上面所说的方案好像也没有多少用处,但是为了保险起见,我还是将自己的wp升级到了2.0.4。 然而问题好像依然照旧,我仍然是只能接受而不能发送,郁闷啊!可是后来我又尝试了申请了一个my.donews结果发现可以给这篇文章发送trackback,这是怎么一回事情,虽然tb不是必须,但是我觉得还是挺有用的。 [...]

  43. [...] TrackBack是一个很时髦的东西,我想试着使用一下,于是就像以下文章发送了我的TrackBack,但是发现我无法在他的文章下面看到我发过来的TrackBack, 背着石头上山的鱼,而别人可以给我发送trackback,这一点让我很纳闷,是不是wordpress出现了问题,于是到google上搜了一下。发现也有人遇到了和我一样的问题:freeman’s blog但是他也没有找到解决方案。 終極邊疆BLOG上给出了一个解决方案,但是他针对的是wordpress2.0,我使用的版本是wordpress2.0.2,他上面所说的方案好像也没有多少用处,但是为了保险起见,我还是将自己的wp升级到了2.0.4。 [...]