作者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
1F:推 yukang:有看有推~ 04/06 19:50
2F:推 PsMonkey:看不懂还是推~ 04/06 20:07
3F:推 showsky:但是在zend_parse_parameters中又没指定type这作用是? 04/06 20:34
要参考 3. 的网页 s 是字串,有点像是 sprintf 的用法
4F:→ 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().
5F:→ showsky:谢谢教学 04/06 20:35
6F:→ showsky:zval *param; 宣告的意义? 04/06 20:36
我看得时候是觉得「似乎是传入参数的物件」,不过没有去尝试,所以就照着范例写…
http://usphp.com/manual/en/zend.arguments.php#example.zval-typedef
7F:推 knuckles:推教学 不过如果想要支援双色字还是得自己写吧 ^^|| 04/06 21:17
8F:→ chrisQQ:欸都,不好意思写得很简陋… 主要也是官网说明有… 就… 04/06 21:31
9F:→ chrisQQ:没特别逐一翻译了,一些参数我也还在测试中ˇˇ 04/06 21:32
10F:→ chrisQQ:主要是不想写论文所以偷懒时的小尝试… 有机会再重新整理 04/06 21:34
※ 编辑: chrisQQ 来自: 203.145.202.66 (04/06 21:41)
11F:推 weiyucsie:先推 04/06 21:41
12F:→ chrisQQ:有问题的话我会尽量提供相关的网址! 04/06 21:56
14F:推 kuwood:推 04/06 22:49
15F:推 amos6064:推推推 04/06 23:56
16F:推 gpmm:push! 04/07 01:24