看板 PHP 關於我們 聯絡資訊
這是一篇教你如何撰寫「將 BBS 轉成 HTML 的 php extension」的教學文。 緣起:(這是廢話,如果您要看本文,請按 page down) 我必須要說,我對 BBS 的喜愛簡直到了偏執狂的地步,雖然 BBS 很簡單 沒辦法提供影片、圖片等等花俏的功能,但就是因為簡單,所以方便快速。加 上中文閱讀習慣與字數的特性,剛好符合 BBS 的瀏覽方式,也因此,世界上 大概也只剩下華人地區在使用 BBS 這玩意兒吧~ 我本身一直在使用 PHP,很早就在學長的指導下開發用 php 去讀 bbs 的 資料,從 web login 到發文、推文等等,一直都慢慢的隨著經驗在改進自己撰 寫的方法。 有些功能,真的是一時寫不出來,放著過一陣子等 knowledge 比較廣的時 候就會變很簡單。當然,這個功能也是… 一直很想把 BBS 上面的顏色完整的在 html 上面呈現出來,不過如果從 php 方面下手的話,不管是用取代或正規表達式,都會很複雜而且很麻煩。其 實 Maple 3.10 by Itoc 早就內建了 bhttpd 的功能,但想要自己用 php 幹 一個的原因就是方便跟其他系統整合。 本篇文章其實就是將 bhttpd.c 中把 ansi 轉換成 html 的部份擷取出來 ,然後依照 php extension 的格式去修改,最後編譯、連結變成 php 的 so 檔,透過 extension load 的方式讓 php 可以直接使用。一方面比較簡單, 因為已經有現成的轉換程式,另外一方面就是 extension 的效率比直接用 php 來處理文章的 ansi tag 好很多。 本文開始:(本文建制環境為 Ubuntu/Apache2/PHP5) 1. 根據這篇文章,先建立好 php extension 的範本 http://usphp.com/manual/en/zend.creating.php#example.simple 2. 接著將 first_module 和 firstmodule 代換成你喜歡的 function name 代換之後大概會變成下面這樣 http://bbs.chrisliu.net/bbsPost.php?bid=A15RM2B9 3. 再來我們要修改接受的變數,我希望傳入的參數是想要轉換的文章路徑 所以是 *s 的指標型態,因此在參考這篇文章後 http://usphp.com/manual/en/zend.arguments.php 代碼大概會變成這樣 http://bbs.chrisliu.net/bbsPost.php?bid=A15RM2M9 4. 接著,請至 bhttpd.c 將 ansi 轉換成 html 的 function 都加進來 bhttpd.c 可從 http://processor.tfcis.org/~itoc/ 取得 感謝 itoc 老大一直維護 maple,另外 ansi 轉 html 的部份 也感謝 [email protected] 撰寫。 經過一場混亂,加進來之後的 code 就變成… http://chrisliu.net/phpextension.phps 5. 這是目前我剛做好,熱騰騰可以編譯的版本… 所以使用下列的方式編譯 應該不會有太大的問題。不過未來當然不排除重新 review code 去優化 complie 的步驟可以參考這個網站 http://blog.ring.idv.tw/comment.ser?i=210 Complie gcc -fpic -DCOMPILE_DL_FIRST_MODULE=1 -I/usr/local/include -I. -I/usr/include/php5 -I/usr/include/php5/Zend -I/usr/include/php5//main -I/usr/include/php5/TSRM -c -o ansitohtml.o ansitohtml.c Linking:產生一個Shared Object~ gcc -shared -L/usr/local/lib -rdynamic -o ansitohtml.so ansitohtml.o 掛上ansitohtml module cp ansitohtml.so /usr/lib/php5/20060613+lfs/ 修改「php.ini」,加上「extension=ansitohtml.so」 然後重新啟動您的Apache Server vi /etc/php5/apache2/php.ini /etc/init.d/apache2 restart 網頁的話請用 phpinfo() 來看看有沒有 load 這個 extension CLI 的話,請直接 php -m 就好囉~ 6. 成功 load 的話,在 PHP 中只要 // $path 可能為 /home/bbs/brd/1/A1111111 這樣 ansi_to_html($path); $fd = fopen ('/tmp/bbs2htm', "r"); $content = fread ($fd, filesize('/tmp/bbs2htm')); fclose ($fd); // 我個人偏好 utf8 所以加了 iconv 轉換 $content = iconv( 'Big5HKSCS','utf-8', $content); // 就會將轉換過的資料暫存在 /tmp/bbs2htm 這個檔案中 // 由於我是用在小站,所以不擔心 lock 與多人存取的問題… // 因為原本 bhttpd.c 中就是另外寫在暫存檔了,因此在我很懶 // 及最小修改的情況下,就暫時指定到同個檔案,當然用在大站的話 // 就可以考慮用文章檔案名稱和看板名稱做 md5 來 cache 起來 // 如果 cache 資料夾已經有轉換過得檔案,且檔案建立時間沒超過多久 // 就不重新轉換 成品的話… 上面幾個連結就已經是了~ 或是自己這篇 http://bbs.chrisliu.net/bbsPost.php?bid=A15RM41N -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 203.145.202.66
yukang:有看有推~ 04/06 19:50
PsMonkey:看不懂還是推~ 04/06 20:07
showsky:但是在zend_parse_parameters中又沒指定type這作用是? 04/06 20:34
要參考 3. 的網頁 s 是字串,有點像是 sprintf 的用法
showsky:然後在 RETURN_STRING(s, 1); 這部分那個1? 是什麼作用啊? 04/06 20:35
這個要參考 http://usphp.com/manual/en/zend.returning.php 這頁 RETURN_STRING(string, duplicate) Returns a string. The duplicate flag indicates whether the string should be duplicated using estrdup().
showsky:謝謝教學 04/06 20:35
showsky:zval *param; 宣告的意義? 04/06 20:36
我看得時候是覺得「似乎是傳入參數的物件」,不過沒有去嘗試,所以就照著範例寫… http://usphp.com/manual/en/zend.arguments.php#example.zval-typedef
knuckles:推教學 不過如果想要支援雙色字還是得自己寫吧 ^^|| 04/06 21:17
chrisQQ:欸都,不好意思寫得很簡陋… 主要也是官網說明有… 就… 04/06 21:31
chrisQQ:沒特別逐一翻譯了,一些參數我也還在測試中ˇˇ 04/06 21:32
chrisQQ:主要是不想寫論文所以偷懶時的小嘗試… 有機會再重新整理 04/06 21:34
※ 編輯: chrisQQ 來自: 203.145.202.66 (04/06 21:41)
weiyucsie:先推 04/06 21:41
chrisQQ:有問題的話我會盡量提供相關的網址! 04/06 21:56
kuwood:推 04/06 22:49
amos6064:推推推 04/06 23:56
gpmm:push! 04/07 01:24