PHP PDO连接PostgreSQL报错 SCRAM authentication requires libpq version 10 or above in解决

26 篇文章 0 订阅
5 篇文章 0 订阅

一、PHP pdo方式连接PostgreSQL数据库
function pdo_query_postgresql($sql)
{
	$num_args = func_num_args();
	$args = func_get_args();       //获得传入的所有参数的数组
	$args = array_slice($args, 1, --$num_args);

	global $POSTGREDB_HOST, $POSTGREDB_PORT, $POSTGREDB_NAME, $POSTGREDB_USER, $POSTGREDB_PASS, $postgre_dbh, $OJ_SAE, $OJ_TEMPLATE;
	try {
		if (!$postgre_dbh) {
			if (isset($OJ_SAE) && $OJ_SAE) {
				$OJ_DATA = "saestor://data/";
				//  for sae.sina.com.cn
				$DB_NAME = SAE_POSTGRE_DB;
				$postgre_dbh = new PDO("pgsql:host=" . SAE_POSTGRE_HOST_M . ';dbname=' . SAE_POSTGRE_DB, SAE_POSTGRE_USER, SAE_POSTGRE_PASS, array(PDO::MYSQL_ATTR_INIT_COMMAND => "set names utf8"));
			} else {
				$postgre_dbh = new PDO("pgsql:host=" . $POSTGREDB_HOST . ';port=' . $POSTGREDB_PORT . ';dbname=' . $POSTGREDB_NAME, $POSTGREDB_USER, $POSTGREDB_PASS, array(PDO::ATTR_PERSISTENT => false));
			}
		}
		$postgre_dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

		$sth = $postgre_dbh->query($sql);
		$result = array();
		if (stripos($sql, "select") === 0) {
			$result = $sth->fetchAll(PDO::FETCH_NUM);
		} else if (stripos($sql, "insert") === 0) {
			$result = $postgre_dbh->lastInsertId();
		} else {
			$result = $sth->rowCount();
		}
		$sth->closeCursor();
		return $result;
	} catch (PDOException $e) {
		$result = array();
		if (stristr($e->getMessage(), "Access denied")){
			$view_errors = array("Database account/password fail, please check db_info");
			$exam_error = array("数据库账户密码错误,请联系系统管理员!");
			array_push($result, $view_errors);
			array_push($result, $exam_error);
		} else {
			if ($postgre_dbh != null){
				$postgre_errorinfo = $postgre_dbh->errorInfo();
				if ($postgre_errorinfo != null){
					$db_error = extractErrorInfo($postgre_errorinfo);
					array_push($result, $db_error);
				}
			}
			$view_errors = array("SQL Exception,".$e->getMessage()."Please check your sql!");
			$exam_error = array("请检查SQL语句!");

			array_push($result, $view_errors);
			array_push($result, $exam_error);
		}
		return $result;
	} catch (Error $error){
		$result = array();

		if (stristr($error->getMessage(), "Access denied")){
			if ($postgre_dbh != null){
				$postgre_errorinfo = $postgre_dbh->errorInfo();
				if ($postgre_errorinfo != null){
					$db_error = extractErrorInfo($postgre_dbh->errorInfo());
					array_push($result, $db_error);
				}
			}
			$view_errors = array("Database account/password fail, please check db_info");
			$exam_error = array("数据库账户密码错误,请联系系统管理员!");

			array_push($result, $view_errors);
			array_push($result, $exam_error);
		} else {
			if ($postgre_dbh != null){
				$postgre_errorinfo = $postgre_dbh->errorInfo();
				if ($postgre_errorinfo != null){
					$db_error = extractErrorInfo($postgre_dbh->errorInfo());
					array_push($result, $db_error);
				}
			}
			$view_errors = array("SQL Error,".$error->getMessage()."Please check your sql!");
			$exam_error = array("请检查SQL语句!");

			array_push($result, $view_errors);
			array_push($result, $exam_error);
		}
		return $result;
	}
}
二、连接时发现如下报错

Unable to connect to PostgreSQL server: SCRAM authentication requires libpq version 10 or above in

三、解决办法

参考文章 https://www.douban.com/note/790907337/
中关于R语言连接PostgreSQL的错误,猜测报错原因应该一致。

以下内容来内上面链接中的原文:

之后,猜测问题发生的原因在于, PostgreSQL10 及以后的版本使用 SCRAM-SHA-256 方法取代了 md5 方法进行密码身份验证,而 RPostgreSQL包 (RPostgre包 也一样) 只支持后者、不支持前者。所以,一个简单的解决方法就是把 PostgreSQL 的密码验证方法调回 md5。
解决过程涉及到两个参数文件: postgresql.conf 和 pg_hba.conf,均在 PostgreSQL 的安装目录下。两个文件的具体作用可参考第二篇文章。
具体操作:
pg_hba.conf 中,末尾处类似
local all all scram-sha-256
的,其中的 scram-sha-256 全部改为 md5 即可;
postgresql.conf 中:
password_encryption = scram-sha-256 # md5 or scram-sha-256
改为:
password_encryption = md5 # md5 or scram-sha-256
在完成修改后,重启 PostgreSQL 。此时,新建的用户及其所有的数据库便改为 md5 密码验证方式,可以通过 RPostgreSQL包 正常连接到R;而在此之前建立的使用 scram-sha-256 方法的用户及其数据库则不受影响,依然使用原方法进行验证,因此似乎也无法通过 RPostgreSQL包 连接到R,也许只能换 PostgreSQL10 之前的版本或等待 RPostgreSQL包 更新了。

因此,在这里,我们的比较可操作的解决办法也是有两个:
1.升级libpq.dll的版本至9.6及以上版本
2.修改PostgreSQL的密码验证方式为md5

其实既然是版本问题,那么还有第三个办法,那就是降低PostgreSQL的版本。不过可能一般不会这么做。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值