作者chrisQQ (ChrisLiu)
看板PHP
標題[心得] 如何撰寫自己的 php extension
時間Tue Apr 6 18:50:09 2010
這是一篇教你如何撰寫「將 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