首页 > Wordpress > [ZT]一個 WordPress plugin 的 debug 過程

[ZT]一個 WordPress plugin 的 debug 過程

2009年5月23日 Galaxy 发表评论 阅读评论

http://blog.chweng.idv.tw/archives/300

這是一個與 WordPress 插件 bug 奮鬥的流水帳,有興趣的人再看看就好,其他人就可以直接跳過啦!

話說這幾天逛了好幾個 WordPress 相關網站,順便更新了幾個我自己站上的 plugin,也寫了兩個新的功能進去。就在一切即將大功告成的時候,熊熊發現 Firefox 的 Html Validator 套件給了我一個沒看過的錯誤圖示。

先解釋一下 Html Validator 的幾種可能檢測情況吧!最好的情況是沒有錯誤與警告,此時會給出一個綠色的勾勾圖示;如果只有警告(warning)的話,則出現黃色的驚嘆號;如果有錯誤(error)的話,則會出現紅色的 X。而這次,檢測結果出現的是一個藍紫色的 A(1 warning),但是檢視原始碼的時候,卻又告訴我沒有問題,真是奇怪……

問了一下朋友,才知道原來那個圖是代表的意思是,網頁中有無法正確解讀的字元存在,並且可用 W3CThe W3C Markup Validation Service 來指出錯誤是發生在哪一行。

前往檢查之後,又發現一個奇怪的現象:如果我直接把網址餵給 W3C 來檢查,會指出哪一行有無法解讀的字元存在,但如果我由自己的電腦開啟網頁,再將原始碼複製給 W3C 檢查,卻又可以通過檢測。

因為我的網頁每次都有些許的不同,所以直接餵給 W3C 所指出的行數,不一定會與我自己從瀏覽器取得的原始碼符合,而且就算真的從原始碼中找相對應的行數,也沒有發現什麼異常的情況,更何況這份原始碼複製給 W3C,一樣還是可以通過檢測的啊!那麼這個奇怪的字元究竟是怎麼出現的呢?為了抓出這個傢伙,一時間還真沒有想到什麼比較好的方法……

經過一天的沉澱,終於想到一個應該可行的方法,就是用 php 的 curl 函式,直接將網頁內容擷取下來,而不透過複製的方式來取得原始碼。果然!將使用這個方法擷取的原始碼餵給 W3C,一樣會指出某一行出現編碼錯誤的訊息。再去查看相對應的行數,果然被我找到問題所在了!雖然還是沒有看到那個神秘字元長什麼樣子,不過總算稍微有點頭緒。

問題的關鍵,就出在 Random Posts for Chinese 這個 plugin 上。因為這個插件會去切割文字內容,來達到摘要的效果。也許就是在切割的過程中出了點差錯……

看了一下 code 後,果不期然,終於發現問題所在,果然是在字元切割上的問題!抓到問題來源後,稍微修改一下 code 然後正式上線……賓果!一切正常了!

Yan Feng 前輩提供的另一個插件 – Comment Hacks 中,就有一個 utf8_trim 函式,可用來處理切割 UTF-8 字元的問題。不過顯然他忘了把這功能也加到 Random Posts for Chinese 中,所以才會出現這樣的異常情況。

其實這個問題,在使用多字元文字(以亞洲國家中日韓為主)的網頁中還滿常發現的,但偏偏大多數的 WordPress plugin 作者多是使用單字元文字的歐美人士,通常都沒有注意到這個問題。因此同樣的情況很可能一再重複發生,必須靠自己來修正這些套件,才能盡量避開這些錯誤。

以上報告完畢,如果你的 WordPress 部落格老是因為這個原因通不過檢測的話,不妨檢查一下所使用的 plugin 中,是否有做切割(strip)文字的動作?那往往就是問題的關鍵所在喔!


http://www.robbin.cc/vb/showthread.php?t=95
我一向是使用這個函式來做中文字元切割
PHP 代碼:

function cut_str($str, $maxlen) {
    $i = 0; $l = 0; $f = true;
    $len = strlen($str);
    while ($i <= $len) {
        if (ord($str[$i]) < 0x80) { $l++; $i++;    //0~128
        }
        elseif (ord($str[$i]) < 0xe0) { $l++; $i += 2;//128~224
        }
        elseif (ord($str[$i]) < 0xf0) { $l += 2; $i += 3;//224~240
        }
        elseif (ord($str[$i]) < 0xf8) { $l += 1; $i += 4;//240~248
        }
        elseif (ord($str[$i]) < 0xfc) { $l += 1; $i += 5;//248~252
        }
        elseif (ord($str[$i]) < 0xfe) { $l += 1; $i += 6;//252~254
        }
        if (($l >= $maxlen - 1) && $f)  {
           $str = substr($str, 0, $i);
           $f = false;
        }
        if (($l > $maxlen) && ($i <=$len)) {
            $str .= "…";
            break;
        }
    }
    return $str;
  }

個人覺得還不錯用….

這是內附的 utf8_trim 函式:
PHP 代碼:

function utf8_trim($str) {
    $len = strlen($str);
    for ($i=strlen($str)-1; $i>=0; $i-=1) {
        $hex .= ' '.ord($str[$i]);
        $ch = ord($str[$i]);
        if (($ch & 128)==0) return(substr($str,0,$i));
        if (($ch & 192)==192) return(substr($str,0,$i));
    }
    return($str.$hex);
}

對 UTF-8 編碼格式沒有太多研究,
不知道哪個比較完美呢?有沒有可能漏掉某些情況沒處理到?

今天朋友告知了一個好用的功能,如果你的 php.ini 有開啟 mbstring 這個 extension 的話,可以用 mb_substr 這個函式來切字,用法跟 substr 完全一樣。

不過切字前記得先用 mb_internal_encoding 來指定編碼方式,在 WordPress 中,可以搭配 get_bloginfo(‘charset’) 來取得 blog 使用的編碼格式,這樣幾乎就萬無一失了!

代碼:

mb_internal_encoding( get_bloginfo('charset') );
$string = mb_substr($string, 0, $length);

我將您的函數做了一點小修正:

function utf8_trim($str) {
$len = strlen($str);
if ( ( ord($str[$len-1]) & 128 ) ==0 ) return($str);
 
for ($i=strlen($str)-1; $i&gt;=0; $i-=1) {
$hex .= ' '.ord($str[$i]);
$ch = ord($str[$i]);
//if (($ch & 128)==0) return(substr($str,0,$i));
if (($ch & 192)==192) return(substr($str,0,$i));
}
 
return($str.$hex);
}

大概是這樣。
評論由 Hemiola 發表 @ 五月 7 日, 2006 6:16 上午

Tags: ,

Related posts

分类: Wordpress 标签: , 233 views
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.

Locations of visitors to this page