Category Archives: Open Source

用 ISBN 抓書本封面

今天在玩 DokuWiki,看到有一個 ISBN 的 Plugin,可以用 ~~ISBN: [ISBN] ~~ 這樣加入書籍的封面,並連到 Amazon 的頁面。不過,中文的書籍大部份在 Amazon 都找不到,所以我就做了一個可以從博客來網路書店抓圖的程式。

程式的邏輯很簡單:判斷 ISBN Country Code,台灣和中國共用 957 和 986 這兩個編號,所以如果是這兩區就送到博客來去查詢;反之則送到 Amazon 去。為了禮貌,程式中也加入了 Cache 機制,以免對兩家書商造成困擾。目前 Cache 利用 ISBN 尾碼分散,短時間來說應該是不會有問題;不過還沒有實作 Cache Expire 機制(需要嗎?) 程式可以在這裡下載。

如果你只是想利用 ISBN 查詢書名,那不需要自己安裝一個。您可以利用 https://pesty.yichi.org/ISBN/ 來查詢,例如您要查詢 ISBN 是 9572231588 的書籍,只要程式去抓取 https://pesty.yichi.org/ISBN/?isbn=9572231588 的資料,就會回傳回兩行資料(以 n 分隔),第一行是書本的 URL,第二行是圖片網址,如果找不到則送出 HTTP 404 Error。回傳結果利用 PHP or PERL 都很好處理,就不在此多作說明了。

我不知道博客來是否有提供額外的 API,如果有的話希望知道的網友告訴我一聲以便改寫。我不太清楚他們是否歡迎這樣的行為,如果不歡迎的話….那我們再來幫其他網路書店創造來客吧 :p

做出來的結果請參考: 這裡

有問題請留言。

MySQL 4.1 使用 UTF8 所遭遇的問題及解決方法

最近換成使用 MySQL 4.1 的人越來越多了,在許多地方也看到了哀嚎聲四起,遇到的狀況不外乎是原本的資料突然都變成不正常了,所以在這邊提供正解。

事實上這個問題不光是使用 UTF8 會有,照理說使用其他語系也會有相同的問題,例如如果我們原本用 GB2312 來存資料,結果現在升級後應該也會有問題。解決之道也很簡單:資料庫是什麼編碼,之後 Client 端程式就用什麼編碼和它溝通。

那要怎麼知道資料庫原本是什麼編碼呢?我在 commit 給 plog 中 adodb 的 patch 中包含了一段檢查 database encoding 的 code:


function _getDbDefaultEncoding($argDatabasename){
   if (!$argDatabasename) {
     return false;
   }

   // We use a SHOW CREATE DATABASE command to
   // show the original SQL character set when DB was
   // created.
   $result = mysql_query("SHOW CREATE DATABASE
        $argDatabasename", $this->_connectionID);
   if (mysql_num_rows($result) < 0 ) {
      // The specified db name is wrong!
      return false;
   }
   $dbInfo = mysql_fetch_row($result);
   $pattern = '/40100 DEFAULT CHARACTER SET (w+) /';
   if ( (preg_match($pattern, $dbInfo[1], $match) > 0) ) {
      return $match[1];
   }
   return false;
}

這個函式會檢查當初資料庫建立的編碼方式,並回傳回來,這樣可以確保我們不是冒然把 MySQL client 的 encoding 設定成 UTF-8 (這是目前看到大多數人的解法)。

接下來,在 SelectDB() 函式中,做以下修改:


function SelectDB($dbName)
{
  $this->databaseName = $dbName;
  if ($this->_connectionID) {
+   $dbEncoding =
+       $this->_getDbDefaultEncoding($dbName);
+   if ($dbEncoding) {
+     mysql_query("SET NAMES $dbEncoding",
+         $this->_connectionID);
+   }
     return @mysql_select_db($dbName, $this->_connectionID);
  }
  else return false;

這樣應該不管原本的編碼為何,讀和寫都不會有問題;唯一要注意的是,如果你的 MySQL 不是 4.1 以上,有些指令並不支援,所以這段 patch 不適用;我也替 pLog 寫了一個 isSupportUtf8() 的 function call, 可以用來檢查是否是 4.1 以上的版本,不過就不再這邊多加贅述了。

P.S. 請注意,如果你沒有學過 PHP,請不要問我該怎麼加入這段程式碼。請尋求你所使用的軟體之開發者的協助。