新XAMPP环境下PHP连接MySQL返回致命错误而非错误码,求原因
我使用XAMPP测试PHP程序多年,近期在新电脑安装了最新版XAMPP并迁移了PHP应用。数据库连接逻辑为先尝试连接生产数据库,失败则尝试连接测试数据库,代码如下:
<?php function dbConnect() { @ $db = new mysqli('localhost', 'live_username', 'live_PW', 'live_db_name' ); $test = mysqli_connect_errno(); if (mysqli_connect_errno()) { @ $db = new mysqli('localhost', 'test_username', 'test_PW', 'test_db_name' ); if (mysqli_connect_errno()) { $test = mysqli_connect_errno(); echo "Error # ".$test."<br/>"; echo 'Error: Could not connect to database. Please try again later.'; exit; } } return $db; } ?>
该逻辑在多台服务器上均能正常运行,但在新电脑上执行首次连接尝试时,抛出如下致命错误:
Fatal error: Uncaught mysqli_sql_exception: Access denied for user 'centr120_genuser'@'localhost' (using password: YES) in C:\xampp\htdocs\cmp\connectdb.php:3 Stack trace: #0 C:\xampp\htdocs\cmp\connectdb.php(3): mysqli->__construct('localhost', 'live_use...', Object(SensitiveParameterValue), 'live_db_name') #1 C:\xampp\htdocs\cmp\index.php(17): dbConnect() #2 {main} thrown in C:\xampp\htdocs\cmp\connectdb.php on line 3
此致命错误导致mysqli_connect_errno()的错误判断逻辑无法执行,请问这是什么原因?
这是因为新版PHP(最新版XAMPP自带的PHP版本较高)中,mysqli默认开启了异常模式。旧版本的mysqli在连接失败时只会返回false,不会抛出异常,而新版本中,连接失败会直接抛出mysqli_sql_exception,你代码里的@错误抑制符无法阻止异常抛出,导致后续的错误判断逻辑根本没机会执行。
方法一:关闭mysqli异常模式
在创建连接前,先设置mysqli的错误模式为传统的错误返回模式,把这句代码加到dbConnect()函数开头即可:
mysqli_report(MYSQLI_REPORT_OFF);
调整后的完整代码:
<?php function dbConnect() { mysqli_report(MYSQLI_REPORT_OFF); @ $db = new mysqli('localhost', 'live_username', 'live_PW', 'live_db_name' ); $test = mysqli_connect_errno(); if (mysqli_connect_errno()) { @ $db = new mysqli('localhost', 'test_username', 'test_PW', 'test_db_name' ); if (mysqli_connect_errno()) { $test = mysqli_connect_errno(); echo "Error # ".$test."<br/>"; echo 'Error: Could not connect to database. Please try again later.'; exit; } } return $db; } ?>
这样连接失败时不会抛出异常,只会返回false,原来的错误判断逻辑就能正常工作。
方法二:改用异常捕获逻辑
保留mysqli的异常模式,使用try-catch语句来捕获连接异常,调整代码如下:
<?php function dbConnect() { try { $db = new mysqli('localhost', 'live_username', 'live_PW', 'live_db_name'); return $db; } catch(mysqli_sql_exception $e) { try { $db = new mysqli('localhost', 'test_username', 'test_PW', 'test_db_name'); return $db; } catch(mysqli_sql_exception $e) { echo "Error # ".$e->getCode()."<br/>"; echo 'Error: Could not connect to database. Please try again later.'; exit; } } } ?>
内容的提问来源于stack exchange,提问作者MiloMal

