Medoo是一款PHP环境下的强大数据库类,初学上手不易,但习惯以后感叹功能十分强大且方便。
但是该类一直有一个不算问题的问题,就是不支持中文(严格来说是非英文)表名,对于喜欢用中文作表名的我来说很不方便。
很多保守派可能会嘲笑:不用英文写代码和数据库的人好意思说是程序员?可是仔细想想这没什么毛病,只是习惯不同而已,而且MYSQL已经明确表态支持任何语言作为库名、表名、字段。
另一方面说,对于这么一款NB且完美的数据库类,不应该留一点点遗憾。
既然作者不支持,怎么办?自己动手改,其实很简单。
要解决问题首先要找到原因,为什么传递的函数写的好好的,到查询那里就显示表不存在?表名在哪里被过滤掉了?
其实很简单,因为medoo太强大了,允许你用[<>]进行联合查询,允许你用()定义别名,允许你用“!”限制条件,但是这些并不是数据库本身支持的,说明Medoo在程序内部进行了解析和处理,一定是解析的过程出现了问题。而这种解析不用想肯定是用了正则表达式,这样问题就简单了。正则匹配中文,这是个古老的问题,一般情况下写正则都会忽略这点,而\w只能匹配英文单词不包括中文。
找到问题了,修改很简单,搜索所有的“a-zA-Z0-9”在 前面插入“\x{80}-\x{ff}”就OK了。其实直接替换成“\w\x{80}-\x{ff}”理论上也是可以的,当然这是配合GBK编码的PHP程序。如果是UTF-8怎么办?插入“\x{4e00}-\x{9fa5}”就行了。
如果担心这样效率会变低,那么提供另外一个思路:“[^\<\>\=\!]”这样也可以,但是我这个没写全,因为很麻烦,针对不同位置的正则代码要分别修改。我懒,就算了。
补充一个知识点:为什么是0x80~0xff这个范围?
# 双字节字符编码范围
GBK (GB2312/GB18030)
x00-xff GBK双字节编码范围
x20-x7f ASCII
xa1-xff 中文 gb2312
x80-xff 中文 gbkUTF-8 (Unicode)
u4e00-u9fa5 (中文)
可是到这里还没完,发现一个问题,使用“表名.字段”查询时,返回结果为空。WHY?!调试代码,调试了很久,发现作者这个变态的家伙,在“function columnMap”函数里,分理表名字段时不是用之前的“a-zA-Z0-9”,而是“\w”,全程序仅有的一个“\w”!我这强迫症,真是..受不了!将这个“\w”前面也加上“\x{80}-\x{ff}”,OK,终于完美了。
2018.02.23更新:
以上在PHP5.4+Medoo1.4.5测试通过。
在PHP7+Medoo1.5.4测试失败,查看源码分析可能是PHP7的PDO原因。
修改Medoo使SELECT设置字段为数组时允许匹配“*”号:
1.5.4版本:
第312行(generate函数),“a-zA-Z0-9”前面加“\*”。
第463、469行(columnPush函数),“a-zA-Z0-9”前面加“\*”。
测试失败,DEBUG输出SQL语句正常,可能是PDO原因。
文章评论