A MySQL 4.1 Story

下面要写的是一篇非常无聊的东西,充斥了大量各式各样的编码、转换、客户端、服务器端、连接……呃,我自己都不愿意去看它,但想一想,写下来还是有点意义的,原因有四:

1. MySQL 4.1 对多语言的支持有了很大变化 (这导致了问题的出现);
2. 尽管大部分的地方 (包括个人使用和主机提供商),MySQL 3 仍然占主导地位;但 MySQL 4.1 是 MySQL 官方推荐的数据库,已经有主机提供商开始提供并将会越来越多;
3. 许多 PHP 程序以 MySQL 作为默认的数据库管理软件,但它们一般不区分 MySQL 4.1 与 4.1 以下版本的区别,笼统地称“MySQL 3.xx.xx 以上版本”就满足安装需求了;
4. 因为 latin1 在许多地方 (下边会详细描述具体是哪些地方) 作为默认的字符集,成功的蒙蔽了许多 PHP 程序的开发者和用户,掩盖了在中文等语言环境下会出现的问题;

简单的说,MySQL 自身的变化和使用 MySQL 的 PHP 程序对此忽略,导致了问题的出现和复杂化,而由于大部分用户使用的是英文,使这种问题不被重视。这里提到的 PHP 程序,主要就 WordPress 而言。
Continue reading “A MySQL 4.1 Story”

Planet 的一个 patch

Planet 是一个比较常用的 feed 聚合器,GNOME、Debian、Perl 等社群都使用这个收集他们相关的新闻,采用的是 Mark Pilgrim 的 Universal Feed Parser (现在这个 feed parser 已经不由 mark 维护,而是放在 sourceforge.net 由几个人共同维护),原来的设置里没法正常处理中文,前几天试用这个东西的时候,顺手做了点修改。这里是 diff 文件,应用在 planetlib.py 上 (我的修改根据的是前几天的一个 nightly 版本)。

但请注意,这仅仅是一个面向简体中文用户的修改,如果你希望支持其他的编码 (比如 ISO-8859-1、Big-5 等),可以参考我的改动变化一下,并不复杂。

因为面对的仅仅是简体中文用户,所以只需要保证不同的来源编码 (gb2312、gbk、gb18030 和 utf-8) 都能够正确转换成目标编码 utf-8 即可。现在使用的策略是这样的,不根据 `xml encoding=` 中的内容来判断编码,首先尝试以 gbk (即 cp936) 解码,不行则用 gb18030 解码,再不行则直接返回 (认为此时是 utf-8)。

这种策略是考虑到简体中文的 blog 一般只有可能使用上述三种编码。(本来没用 gb18030,但在测试的时候遇到一个 blog 的 RSS 有个地方 gb2312 无法解析,换用 gb18030 就 OK 了,说明 `xml encoding` 有的时候也是骗人的…)

说到 Planet,类似的程序还有一个基于 WordPress 和 Magpie Feed parser 的插件,feedwordpress,试用了一下没发现什么问题,能够根据源编码自动判断并转换成 utf-8。但要小心不能正常处理 UTF-8 的 MySQL 服务器。

好吧……我承认就在我自己的机器上遇到了这个问题,从插件怀疑到 wordpress,再怀疑到 php,最后终于发现原来是 MySQL 这小子坏事,网上好像也见到类似的情况。

Win32 下开发 Apache2 Module 起步

Apache 的模块是很有意思的东西,原来 O’Reilly 有本 Writing Apache Modules in Perl and C,算是这方面的终极宝典,可惜此书名不副实,Perl 的内容占了绝大部分,C 的内容几乎是一笔带过 (也难怪,作者就是 mod_perl 的作者嘛),而且这本书是 1999 年写的,也是按照 Apache 1.3 的内容来写的,和现在 Apache2 的情况已经有了不少差别。

而且网上有的教程都是讲 Linux 下的配置过程,问题在于我自己在测试开发的时候是要用 Win32 下的 Apache 的,所以只好自己搞定。

我在网上 google 了一下,没找到什么详细的资料,考虑可能有朋友需要这种上手的教程,把今天的步骤写下来。

安装 Apache 2.

这里 找到一份最简单的 Apache2 module 源代码,这里有这份代码的详细说明,不过讨论是 Unix/Linux 下的情况。

如果你没有安装 Visual C++ 6.0 或者 Visual Studio .Net 的话,可以安装 Visual C++ 2003 Toolkit,这是免费的 M$ 的 C++ 编译器。

在 mod_tut1.c 的开头加一句:

#ifndef WIN32
#define WIN32
#endif

把 Apache2 的头文件和库文件目录加入 INCLUDE 和 LIB 环境变量中。可以参考下面这个 batch file:

set LIB=%LIB%;E:\Progra~1\Apache~1\Apache2\lib
set INCLUDE=%INCLUDE%;E:\Progra~1\Apache~1\Apache2\include

用 `cl /c mod_tut1.c` 编译,生成 `mod_tut1.obj`。

用 `link /DLL mod_tut1.obj libhttpd.lib` 链接起来,生成 `mod_tut1.dll`。

把 `mod_tut1.dll` 改名为 `mod_tut1.so`,复制到 Apache2 安装目录的 modules 子目录下。

在 httpd.conf 中加一句:

LoadModule tut1_module modules/mod_tut1.so

重新启动 Apache,访问 http://localhost/ 一次,然后打开 access.log,看看里面有没有新增“A request was made”的内容,有的话,说明搞定了。:)

当然,上面的内容也不是开发的实际过程,具体的开发过程,前面提到的那本书和 Apache 的文档里描述得更详细,这些,无论是 Unix/Linux 还是 Win32 都是共通的,所以也就无需我饶舌了。

Web Developing Ideas

现在做的东西基本上和 Web 无关,所以也就很久找不到什么 Web 标准相关的东西,有的时候太注重效率了,做起东西来束手束脚的,也很不爽。

前一阵子我用 C 写过一个简单的模版库,用于高效率,但保留一定灵活性的 CGI 程序,不过这份代码已经和我的 C 盘一同被格掉了,所以现在可以放弃它,开始一些新的想法。

最近比较喜欢的几个东西有,用 PHP5 调用动态链接库 (.so) 文件的方式、在 PHP5 下使用 sqlite 轻量级数据库、用 lua 语言的一个扩展 CGILUA 写 CGI 程序、Perl 的 Template Toolkit,等等。时间紧张,来不及加上链接,有兴趣的可以自己 google 一下,不难找到,前两个 php.net 有文档,最后一个 O’Reilly 出了一本书。