第六代禁片:quercus 数据库中文乱码问题研究, 解决了.

来源:百度文库 编辑:偶看新闻 时间:2024/04/28 11:27:15
quercus 数据库中文乱码问题研究, 解决了.2011-03-23 22:56

1.给mysql加上详细日志,以便分析问题所在

修改my.ini ,在文件最后加一行

log=mysql.log.txt

重启mysql server, 只要有SQL执行,就会生成一个日志文件 mysql.log.txt ,在data 目录中.

 

2.在quercus 中执行PHP,做一次mysql_connect , 再查看mysql.log.txt日志

SET NAMES latin1

这就是问题所在.

 

3.去quercus源代码目录里搜索:    'latin1'

 

Mysqli.java(228):
可能就是关键!

4. 修改源码, 干掉bug.

经测试,

将这两个文件的 latin1 改为  utf8.

编译,更新相关文件 .

问题解决了!  done!

 

5.测试

the php code:

the mysql database :

用户282 , "用户"这个中文终于正确了.

 

 

6.下一步.  续集:

到目前为止, 暂时只解决了写入mysql时中文正常.

从mysql读出时,还有问题.  估计问题在于:

\src\com\caucho\quercus\lib\db\MysqliResult.java  (约 line 990 )

2011-03-24 ,花了一上午的时候研究,发现问题果然在这里, 并且已经搞定了.

将MysqliResult.java 文件line 934开始的 getColumnString函数修改为如下的内容:

意思大概是在返回数据之前的,处理编码问题

[code]

    protected Value getColumnString(Env env, ResultSet rs,
            ResultSetMetaData md, int column) throws SQLException {
        // php/1464, php/144f, php/144g, php/144b

        // The "SET NAMES 'latin1'" in Mysqli is important to make the default
        // encoding sane

        Mysqli mysqli = getMysqli();

        if (rs instanceof QuercusResultSet) {
            QuercusResultSet qRs = (QuercusResultSet) rs;

            int length = qRs.getStringLength(column);

            if (length < 0)
                return NullValue.NULL;

            // XXX: i18n
            StringBuilderValue sb = new StringBuilderValue();
            sb.ensureAppendCapacity(length);

            qRs.getString(column, sb.getBuffer(), sb.getOffset());
            sb.setOffset(sb.getOffset() + length);

            return sb;
        }

        Method getColumnCharacterSetMethod = mysqli
                .getColumnCharacterSetMethod(md.getClass());

        String encoding = null;

        try {
            if (getColumnCharacterSetMethod != null)
                encoding = (String) getColumnCharacterSetMethod.invoke(md,
                        column);
        } catch (Exception e) {
            log.log(Level.FINE, e.toString(), e);
        }

        // calling getString() will decode using the database encoding, so
        // get bytes directly. Also, getBytes is faster for MySQL since
        // getString converts from bytes to string.

        byte[] bytes = rs.getBytes(column);

        if (bytes == null)
            return NullValue.NULL;

        StringValue bb = env.createUnicodeBuilder();
        String value = null;
        try {
            value = new String(bytes, "UTF8");
            //System.out.println(value);
            bb.append(value.getBytes("UTF8"));
            //System.out.println(bb);
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return bb;
    }

[/code]

good, 到这里 quercus操作mysql的乱码问题,圆满解决了.

            value = new String(bytes, "UTF8");
            bb.append(value.getBytes("UTF8"));

这里要来两次, 原因我也不清楚, 我是试误试出来的. 本人PHP算得上精通, java只知道个皮毛, 将就能用就行了. 

另: 再一步, 搞定eval的中文乱码问题. 

想法大约是修改eval函数的实现: 在eval函数体的第一行, 加入几句,把传进来的参数, 编码给转换回去.