首先说明一下我的应用环境,免得误会:
服务器:win2000、sybase 11.92(cp936字符集)、apache2、php5。
开发环境:ubuntu linux、apache2、php5,数据库直接连接服务器。
以前使用winxp的时候,在php中连接sybase数据库非常方便,再加上使用adodb类库,就更爽了,唯一的一点麻烦就是由于cp936不是sybase 11.92标准的字符集,是硬从sybase 12里面套过来的,所以在连接数据库,执行connect方法的时候也许会有一个warning警告,不过不影响使用,在connect前面加上@屏蔽掉即可(注意,这也是我在遇到本文所述问题时,花了很大时间都找不到问题的直接原因,罪过啊)。
但是,在系统切换到ubuntu下之后,突然发现一个连接sybase数据库的php程序不能用了,错误信息为:
[17-Jun-2006 01:35:48] PHP Fatal error: Uncaught exception ‘ADODB_Exception’ with message ‘sybase error: [0: ] in EXECUTE(“select count(1) as c from icktz where datepart(yy, blrq) = 2006 and blxz like “�°�%””)
‘ in /media/hdd5/php_includes/adodb/adodb-exceptions.inc.php:76
Stack trace:
#0 /media/hdd5/php_includes/adodb/adodb.inc.php(879): adodb_throw(‘sybase’, ‘EXECUTE’, 0, ”, ‘select count(1)…’, false, Object(ADODB_sybase))
#1 /media/hdd5/php_includes/adodb/adodb.inc.php(854): ADOConnection->_Execute(‘select count(1)…’, false)
#2 /media/hdd6/websoft/fwolfweb/tools/work_stat/work_stat.php(396): ADOConnection->Execute(‘select count(1)…’)
#3 /media/hdd6/websoft/fwolfweb/tools/work_stat/work_stat.php(659): WorkStat->Rsql(‘select count(1)…’, ‘jygl’)
#4 /media/hdd6/websoft/fwolfweb/tools/work_stat/work_stat.php(241): WorkStat->StatXysc()
#5 /media/hdd6/websoft/fwolfweb/tools/work_stat/index.php(32): WorkStat->GenerateCache()
#6 {main}
thrown in /media/hdd5/php_includes/adodb/adodb-exceptions.inc.php on line 76
注意其中有一处为乱码“�°�%”,于是怀疑是编码的问题。这个程序中涉及到编码和字符集的地方,是由于php源码使用的都是utf8编码,而sybase使用cp936编码,所以执行sql的时候要转换为gbk,执行结果要显示的时候又要转换为utf8编码。但是反复检查、增删编码处理部分,除了错误信息由乱码变为正常汉字之外,没有任何进展。
没办法,重新写一段最简单的数据库连接程序测试一下:
< ?php
require_once('adodb/adodb.inc.php');
$db = &ADONewConnection('sybase');
$db->Connect(‘server3’, ‘sa’, ”, ‘dbname’);
$rs = $db->Execute(‘select 1’);
?>
运行错误如下:
Warning: sybase_connect(): Sybase: Unable to connect in /media/hdd5/php_includes/adodb/drivers/adodb-sybase.inc.php on line 126
这才恍然大悟,原来根本就没有连接上数据库,自然在执行sql的时候出错。要问刚才为什么没有发现,我不是加上@屏蔽了错误信息嘛。继续分析,上面这段代码原来在winxp客户端调试的时候是绝对能够连上服务器的,怎么在linux下就不行呢,又将服务器名更换为ip地址:端口,就成功了。
可能是由于linux下没有netbios(正如linux无法使用“ping 机器名”命令一样),还可能是linux下没有安装sybase open client,设置dsedit,总之,在linux下连接sybase服务器,只能使用“机器名:端口号”作为hostname,无法直接使用主机名。
于是,在程序中增加一部分字段判断主机操作系统,对hostname进行赋值的语句,问题顺利解决:
if (‘/’ == $_SERVER[“SCRIPT_FILENAME”]{0})
$host_srv = ‘192.168.0.1:5000’;
else
$host_srv = ‘server3’;
$server[0][‘dbtype’] = ‘sybase’;
$server[0][‘host’] = $host_srv;
……