欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

[原]WordPress 3.9使用PostgreSQL数据库问题的解决_MySQL

程序员文章站 2022-06-05 17:58:17
...
WordPress

我一向不喜欢mysql,这事在blog上说过很多次了。所以在我部署的几个wordpress实例中,有部分是使用postgresql数据库的。

用pgsql代替mysql的最大好处是资源可以节约很多。mysql即使只用MyISAM引擎,占用的内存也比标准配置的pgsql大得多——在跑同样的WP应用情况下。更不用说pgsql提供的功能比mysql的InnoDB还多——虽然在WP中用不到。

但是因为WP在代码中是直接使用mysql的,要实现数据库的更换,需要一个插件:PG4WP。不过它的最新版本也已经是两年前的1.3.0了,相当OUT,但是没办法,没有别的选择。

这个插件的实现原理是:动态替换wp-db.php的内容,把其中的mysql API替换为pgsql API(实际上是替换为一套中间API,然后可以通过配置选择使用mysql或是pgsql),最后通过eval运行这个替换后的wp-db.php。

eval……这个……的确比较简单粗暴一点,但是直接有效,性能也基本没有影响(pgsql对mysql的性能优势足以弥补PHP的这点性能损失)。

但是昨天更新到最新的WordPress 3.9以后,发现网站打不开了,看了一下日志,有这样的错误:

2014/05/04 22:16:22 [error] .... FastCGI sent in stderr: "PHP message: PHP Warning: Missing argument 3 for wpsql_result(), called in /.../wp-content/pg4wp/core.php(32) : eval()'d code on line 755 and defined in /../wp-content/pg4wp/driver_pgsql.php on line 58PHP message: PHP Warning: pg_fetch_result() expects parameter 1 to be resource, boolean given in /.../wp-content/pg4wp/driver_pgsql.php on line 59PHP message: PHP Fatal error: Call to undefined function wpsql_errno() in /.../wp-content/pg4wp/core.php(32) : eval()'d code on line 1531" while reading response header from upstream, client: xx.xx.xx.xx, server: xxxxxx, request: "GET / HTTP/1.1", upstream: "xxxxx", host: "xxxxxx"

基本原因是两个:

1、wp-db.php中 调用 mysql_result() 的参数与 pg_fetch_result() 要求不一致(wpsql_result就是pg4wp包装的中间API函数之一),具体在wp-db.php中的第755行,这里只使用了两个参数,但wpsql_result需要三个参数,而且wpsql_result中未处理$result为FALSE的情况。

2、wp-db.php中调用了mysql_errno(),但是pg4wp包装的中间API未实现这个函数,具体在wp-db.php中的第1531行。

放狗搜了一下解决方案,找到插件论坛上这两个帖:

http://wordpress.org/support/topic/not-working-with-39-44
http://wordpress.org/support/topic/not-working-with-39

其中第一个帖比较好地解决了第一个问题,但第二个帖对第二个问题的解决方案不好。因为这个方法是直接修改wp-db.php,如果以后WP再升级,这种修改将会被覆盖,所以还是在pg4wp里修改比较好。

最终解决方案,在driver_pgsql.php中找到wpsql_result函数,然后作如下修改:

function wpsql_result($result, $i, $fieldname = null) {		if (is_resource($result)) {			if ($fieldname) {				return pg_fetch_result($result, $i, $fieldname);			} else {				return pg_fetch_result($result, $i);			}		}	}	function wpsql_errno($conn) {		if (pg_last_error===FALSE) {			return 0;		} else {			return -1;		}	}

保存后再访问网站已不再出错。

话说从PHP5.5开始传统的mysql API已经被确定为过时不能再使用,但是最新的3.9版WordPress还是绑定在mysql上。虽然据说已经换成了PDO,并且只在没有PDO的情况下使用旧的API。另外,在未支持PDO的旧版WP上也可以用WP DB Driver这种插件来支持PHP5.5,但这毕竟不是长久之计,而且这货只支持PDO-mysql和mysqli,并不能使用PDO驱动其它数据库(比如SQLite或pgsql)。

据WP官方十年前的说法《Using Alternative Databases》是因为除了接口不同以外,SQL语法上也有不同,所以才不考虑mysql以外的数据库。但问题是也没有看到WP用到了什么高级mysql技术,pg4wp的简单粗暴方式就可以解决,唯一能想到的理由就是:

改用其它数据库之后插件之类的兼容性没法保证。