跳到网页内文区。

:::

旅舍更新日志 卷二


日期: 3.31.’03.

旅人留言本终於重开了~!哦呵呵呵呵呵~! ^_*'

关闭了两年,留言本终於得以重见天日了。之前的主程式是 1998 年中写的,距今已经快六年了。原来的程式问题很多,几年来虽断续修正一些 bug ,但几个重大的问题却迟迟无法突破。为了避免一天到晚在东挖西补,我毅然决定把留言板整个停掉,整个重写。但因为这些问题都很大,一直无法突破,过了几个月还是想不出办法,就整个搁置下来了。就这样,一搁就搁了两年。

最近这几个月来,我的另一个 PHP 网站计划— Monica —逐渐有了成果,并突破了几个重大的难关。正好上星期阿光要问我 Linux 的问题,在 ICQ 上找不到我,在 ICQ 上留话,催我快弄一个留言板出来,以便我不在也能留言问我。我想到,何不把 Monica 所累积的经验,转移过来呢?把 PHP 的 Monica ,移植到 CGI/Perl 或 mod_perl 环境中,会有什么结果?我也很想考考自己,以我现在的能力,写一个留言板,要花多久时间?这就是 Selima 计划,也就是大家看到的,新的旅人留言板了。移植的工作,花了一个星期左右。 PHPCGI/Perl 或 mod_perl 差别不小,移植的过程多少有点阻碍,但现在看起来,应该算是成功了。 ^_*'

Monica/Selima 所解决的问题,正好也是旧的旅人留言板的主要问题。新的旅人留言板,改善了下列功能:

  1. 留言不再用 <pre>…</pre> 显示,用一个 a2html() 函式,将留言转为 HTML ,在保留原留言格式外,也解决了断行的问题。
  2. 加上语言切换的功能,将原有的中英对照分开,改分成繁简中文和英文三个语言切换。
  3. UTF-8 存留言,并加上万国码处理能力,以解决外地来的朋友,留言会变乱码的问题。
  4. 改用暂存表单转向,所有的页面都是用 GET 来显示,不再在 POST 上显示页面,以避免在 POST 中按下重新整理,会造成重覆留言的问题。
  5. 留言的 E-mail 不会再直接显示,以避免被广告商的 E-mail 扫描程式扫描,发广告信,造成留言的人困扰。
  6. 留言分页原来是以笔数分类,现改以留言的量分类,避免每页长度多寡不一。
  7. 针对 mod_perl 的特性而写,并相容於 CGI/Perl 和命令列模式,执行的效率提高,也提高执行的弹性。

其她还有很多,不及列举。可惜的是,因为 Selima 的架构,用到很多自己写的函式库,要把它们一一放到网站上,颇为困难,更别说要让人看得懂原始码了。无法建置成开放原始码的专案,甚憾。

因为留言板资料档格式改变,暂时还看不到旅人留言本的旧留言。等我整理完,转完档后,会再放上来。

Selima这个字,是来自阿拉伯的女生名字,意思是和平peace。时值美伊战争,美国不顾联合国反对,强行入侵伊拉克,造成无数无辜生命的死伤。取Selima这个名字,一方面为哀悼这些无辜的生命,也希望战争早点结束,让和平早日回到阿拉伯世界。


日期: 11.5.’00.

旅舍依玛经历不少的改变,在这里总结一下。

首先,七月中以后,家里的 ADSL 固接宽频网路终於接通了,旅舍和女声也从原本借用益华主机,改搬到家里的电脑上。搬迁工作比预期简单,因为两边都是 Windows 2000 伺服器,我已经对 Windows 2000 IIS 5.0 很熟悉了,没什么改变。唯一的问题是:我的电脑只是 Pentium Ⅱ 233 ,拿来做主要的 Win32 伺服器,跑得很辛苦。

旅舍和女声搬迁后,我已经没有顾忌了。八月中辞掉益华的工作,用离职保证金买了新的电脑 Pentium Ⅲ 800 当新的伺服器,作业系统使用 RedHat Linux 6.2 (现在已经升级到 7.0 )。刚换 Linux 的时候,真的很辛苦,因为和以前熟悉的 Win32 环境差太多了,整个概念完全不一样。不过换了一个不错的新工作,公司里有一整个书架的 Linux 书,像图书馆一样天天把书借回家。一直到我对 Apache 熟悉以后,才把旅舍和女声网站搬到新的 Linux 伺服器上。在女声编辑手记上的日志记载,这天是 2000 年 9 月 16 日,大约是买了新伺服器后一个月左右。

搬迁到 Linux Apache 最大的改变在於 HTTP 标头的问题。原本在 IIS 下并不是用 CGI ,而是用 ISAPI PerlIS 来执行程式, PerlIS 无法设定正确的 HTTP 标头,所以必需手动设定 HTTP 标头。可是回到 Apache CGI 下,直接送出完整 HTTP 标头会导致错误,所以只得重写所有的 HTTP 标头。

接下来的事情,只能用紧锣密鼓来形容。

9 月 26 日,做出了留言板使用说明,在女声订阅页上加上求助讯息,加上 HTTP 403 Forbidden 自订错误讯息。这些都是很久以前就想写的说明。留言板说明主要是在断行的问题上:留言板不会自动断行。原则上我不打算自动断行,因为我玩 BBS 的时候,已经习惯了手动断行的散文诗格式。可是留言板断行问题仍然是个很头大的问题。我参考过蕃薯藤、 Kimo 讨论区断行处理方式,还没有找到一个比较好的解决方法。这是个仍待解决的问题。

女声订阅页加上了女声编辑的 E-mail ,以便无法订阅时有路可循。 HTTP 403 是 Forbidden ,用来保护网站管理程式和女声订户资料。

9 月 28 日,做出了 robot.txt 。这是用来告诉外面的搜寻引擎,哪些地方不可以拿去做全文检索资料库。这样可以避免搜寻引擎把网站管理程式等等的东西都拿去建档了。

10 月 11 日,网站改用 mod_perl 。这是另一个重要的里程碑。因为公司不用 Perl ,所以一直不知道该怎么用传说中的 mod_perl 来加强网站程式效率。后来我找到了 mod_perl 和 mod_perl 的安装、设定说明,重新安装整个 Apache 伺服器。没想到 mod_perl 的 HTTP 标头处理方式又和 Apache CGI 不一样。为了避免日后同样的困扰,我舍弃手动设定标头,改用 CGI::header() 模组来处理 HTTP 标头。同时我也拿掉自己写的 time2str() ,改用 HTTP::Date::time2str()

改用 CGI::header() 处理标头后,解决了另一个问题: mod_perl 无法持续连线。只要使用 CGI::header() ,就能够启动 Apache::Registry 内部的 HTTP 标头解析引擎,处理连线的相关问题。

我开始舍弃过去的做法。过去为了避免载入外部模组浪费系统资源,我尽量自己写所需要的模组。现在我尽量引用别人写好的外部模组,以保持系统的相容性。这是很重要的观念改变,尤其在 Perl 和 UNIX 程式写作观念上:合作。 Perl 程式应该是不同人努力合作的成果,而不是一个程式单打独斗处理所有的问题。

UNIX 环境也是。不同程式、行程间相互呼叫、配合、传递讯息,以得到结果。 Win32 也可以这样,只是工具太少,而且所耗的系统资源太多。这也违背了 Win32 环境最初的设计目标。

这时候,才真正进入了 UNIX 的世界,一个和 DOS/Win32 完全不同的世界。

另外, mod_perl 会载入所需模组并常驻在 Apache 行程中,会造成模组变数的混淆。我把原来在共用模组设定的变数,如 $ID 、$THIS_FILE ,搬到个别程式里设定。为了避免不同网站的共用模组,因为常驻时名称相同而混淆,我也更改了共用模组的名称。

我写了一个有点复杂的算式计算留言本每一册的最后更新日期。这个算式后来还是改掉了,以避免浏览器快取的时间计算混乱。

我下载了 W3CHTML 认证程式网站,开一个虚拟主机来执行。

同一个晚上,我用 gethostbyname() 写出比较有效的计数器网域判别准则。我也小小修改了前面所提,留言本最后更新日期的算式,以解决没有留言时无法计算最后更新日期的错误。另外,留言存档后的自订 HTTP 303 See Other 重新导向讯息,因为 mod_perl 会自行追加 HTTP 303 讯息,导致讯息长度错乱,使浏览器无法判断讯息长度。我暂时拿掉讯息长度 HTTP Content-Length 标头,以解决问题。

10 月 19 日,我在每个档案开档时加上了 flock() 档案锁定,以避免档案同时读写错乱。这是很久以前就该做的,可是因为一直不清楚 flock() 档案锁定的做法,所以没加上去。这两天仔细读了 flock() 的相关说明,觉得很有效,就加上去了。另外,因为使用了新的档案锁定方法,我也重写了女声订阅程式的流程。女声订阅程式流程还要再改写,以解决另一个问题:档案最后更新日期的判定方式。

其次,我也写了自订的 HTTP 500 伺服器内部错误讯息,并栏截了开档错误,产生 HTTP 500 讯息,以解决网站管理程式重建网页时,网页明明没有更新,却毫无警告讯息的老问题。

10 月 27 日那个周末是另一次重期的日期。我把之前想得到所有的大小 bug ,利用两天三夜的周末假期都解决了。分列如下:

  1. 栏截了所有的档案读写和其它系统函式的错误,并产生 HTTP 500 错误讯息,以更严密地保护程式正常运作。 HTTP 500 原本以 exit() 结束,改以 die 结束,在伺服器错误记录中留下记录。
  2. 重写访客计数器的流程,减少不必要的档案锁定,避免计数器卡死。计数器改以 grep() 判定内部位址。
  3. 摸清楚了 cookies 的详细运作传递方式,简化了计数器的 cookies ,停用 CGI::Cookies 模组,改用 CGI::header() 简化处理。
  4. 摸清楚了 GD 模组的运作方式,简化了计数器、最后更新日期、订户人数图形的处理。
  5. 找到了判别网路作业系统的方式,改写了 Win32 下的安全管制判别流程,并改以 getgrnam()getpwnam() 来做 Linux 下的安全管制。

10 月 28 日星期六,我改写了所有网站管理程式的介面和资料库,把关键字加上去,终於把不同的关键字整合进网页中。我想做好网页的关键字系统已经想了很久了。我顺便改写了相关连结的设定介面,提供更大的功能和弹性。另外,我也写了旅舍的著作权声明和隐私权声明,并把旅舍中的女声著作权声明连结到女声去。

隐私权声明是我之前一直想写的。既然前一天我把 cookies 的传递细节弄清楚了,就顺便一起写出来。希望这可以提醒大家不要在网路上乱留个人资料。至於著作权声明嘛…原则上我很讨厌著作权这种玩意儿。可是最近有些商业网站太过份了,而且有些莫名其妙的人开始对我的网站和我的文章感兴趣。(不知道我招惹到什么了?)为了避免不必要的麻烦,还是写清楚比较好。

10 月 29 日星期天,我改进了自订错误讯息,栏截自订错误讯息本身的开关档错误,并在发生自订 HTTP 500 伺服器内部错误时,寄一封信通知网站管理者。

解决了之前另一个问题:因为程式无法处理 If-Modified-SinceHTTP 标头,而且最后更新日期按照先前所述,会追溯到先前的留言日期,导致浏览器在重读网页时,快取的日期和资料内容错乱,使浏览器卡死。我决定舍弃前述的最后更新日期算式,改以留言板程式本身和留言板资料档的最后更新日期为准,以方便浏览器快取资料更新。我并且加上了对 If-Modified-Since HTTP 标头的支援,加上了 HTTP 304 Not Modified 自订讯息,以支援浏览器快取功能。

我写了自订 HTTP 405 Method Not Allowed 错误,避免有人用 PUT / DELETE / TRACE 等…连上来。虽这种事情应该不可能发生,可是一旦发生了却没有处理,是很笨的事。

到这里,网站程式算是告一段落。我想得到的大小问题解决得差不多了,也松了一大口气。

11 月 2 日,旅人留言簿资料已经接近 600笔,原来的资料库引擎已经超出负荷,出现严重停滞现象。经过执行速度比对实验后,我改写了资料库引擎。原来程式是一笔一笔比对,改用整批比对的方式,虽然有点取巧,但大幅度加快了资料库解析速度。现在的新资料库引擎,即使超过 6,000 笔留言,仍保持极快的速度。超过 10,000 笔以后呢?那以后再说吧。原则上,留言簿留言我不打算用 SQL 资料库,维持最基本的原则:可携性。我希望整个网站随时可以搬到别的伺服器上,不需要依赖外在环境的特殊因素,例如:是 MySQL ? mSQL ? PostgreSQL ? MS-SQL ? Access ODBC ?还是 IBM DB2 ?

因为网站工程告了一段落,我开始打算释出旅舍依玛的原始程式码。这个工程有点浩大,因为即使我程式码写得很清楚,可是注解却不多,如果要释出,还要加上很多注解,才能让别人看得懂。

前天 11 月 3 日周末,我尝试把旅舍搬回 Win32 IIS 的环境下,发现问题远比我想像的复杂。 PerlIS 无法正常处理 HTTP 标头、 IIS CGI 无法正确设定程式执行目录, Apache mod_perl Apache::Registry 模组处理 CGI::header() 的方式也很特殊。我花了三天、翻遍 Perl 、mod_perl 的说明和讨论以后,总算写出程式,改用绝对档案路径,以取得最大的相容性,并根据特殊情形修正 HTTP 标头。我并且解决了前述的问题: mod_perl Apache::Registry 模组下, CGI::header() 自订 HTTP 错误会自动加上内文,导致内文长度错乱乱,浏览器无法判别的问题。现在程式若是在 mod_perl 下,不会送出自订错误讯息内文,将内文交给 mod_perl 处理。

我重写了图形程式(计数器、上次更新日期、订阅人数)处理流程,以和其它程式的流程惯例一致。

想做的事还有一些。女声订阅程式的流程还要再改写,先处理订阅要求,再判断最后更新日期。现在的顺序是倒过来的。另外,要加强程式的注解,才能释出程式码。而且,还要加上记录网站版本的变更。

释出程式码其实没什么大不了。现在的留言板、计数器的免费程式码到处都是。但总是一个重要的里程碑。


目录 | 第一页 | 前一页 | 1 | 2 | 3 | 4 | 5 | 下一页 | 最末页