题 new mysqli():如何拦截“无法连接”错误?


我这样做 (是的,我使用了错误的连接数据,这是强制连接错误)

26 try {
27     $connection = new mysqli('localhost', 'my_user', 'my_password', 'my_db') ;
28 } catch (Exception $e ) {
29     echo "Service unavailable";
30     exit (3);
31 }

但PHP正在做这个php_warning:

mysqli :: mysqli():( 28000/1045):用户'my_user'@'localhost'拒绝访问(使用密码:YES)

在示例中,我使用错误的连接数据来强制连接错误,但在现实世界中,数据库可能已关闭,或者网络可能已关闭......等等。

题: 有办法吗? 没有压制警告, 拦截数据库连接的问题?


16
2018-03-21 16:53


起源




答案:


你需要告诉mysqli抛出异常:

mysqli_report(MYSQLI_REPORT_STRICT);

try {
     $connection = new mysqli('localhost', 'my_user', 'my_password', 'my_db') ;
} catch (Exception $e ) {
     echo "Service unavailable";
     echo "message: " . $e->message;   // not in live code obviously...
     exit;
}

现在你将捕获异常,你可以从那里拿走它。


40
2018-03-21 17:04



如果您遇到致命错误,请尝试: $e->getMessage() - argon
向最终用户显示错误消息是一个非常糟糕的主意。这是一个潜在的安全风险,最好将错误记录到文件并显示通用错误消息。 - Rob Sedgwick
@RobSedgwick这就是我添加评论的原因 not in live code obviously...... - jeroen
@YourCommonSense要说明SO发生了什么以及有关异常的可用信息? - jeroen
这很有才华。我已经为服务器设置了我的服务但我喜欢在本地机器上默认使用localhost所以我使用connect_errno检查是否存在连接错误,然后转到localhost。这是一个更好的解决方案,因为它没有显示错误 - Thomas Williams


对于PHP 5.2.9+

if ($mysqli->connect_error) {
    die('Connect Error, '. $mysqli->connect_errno . ': ' . $mysqli->connect_error);
}

您也希望将报告模式设置为严格级别,正如jeroen建议的那样,但上面的代码对于专门检测连接错误仍然很有用。这两种方法的结合是推荐的 PHP手册


10
2018-03-21 16:58



@运算符有很多问题,应该避免。 Jeroen有一个更好的解决方案。 - GordonM
这是正确的方法。不幸的是,这不会正确报告一个不存在的数据库,我在这里提供了一个解决方案。 - HoldOffHunger


检查 $connection->connect_error 值。

请参阅此处的示例: http://www.php.net/manual/en/mysqli.construct.php


2
2018-03-21 16:59



好的,但我不需要挑衅警告..没有压制警告...... - realtebo


如果我们只做简单的if有什么区别?如果简单的IF做了一切,为什么我会费心去尝试?

if ($mysqli->connect_errno)
{
   echo "connection error, exiting...";
   exit;
}

// everything was fine...

echo "hello, connection was established!"


-3
2018-01-06 12:55



如果没有尝试连接$ mysqli,则无法显示connect_erno,这是连接connect_errno的位置以及显示警告消息的位置。 - HoldOffHunger


mysqli_report(MYSQLI_REPORT_STRICT);,如别处所述,给我一个错误并立即停止脚本。但这下面似乎为我提供了理想的输出......

error_reporting(E_ERROR);

$connection = new mysqli('localhost', 'my_user', 'my_password', 'my_db') ;

error_reporting(E_ERROR | E_WARNING | E_PARSE);

if($connection->connect_errno)
{
  // Database does not exist, you lack permissions, or some other possible error.
    if(preg_match($connection->connect_error, "Access denied for user"))
    {
        print("Access denied, or database does not exist.");
    }
    else
    {
        print("Error: " . $connection->connect_error);
    }
}

尝试使用try..catch()捕获此错误将失败。


-3
2018-05-30 00:30



告诉网站用户他们没有任何权限是没有必要的。你对错误处理的想法本质上是错误的。 - Your Common Sense
@Your Common Sense:如果该站点用户也是db-admin团队的成员,那么告诉站点用户有关数据库权限的一切都是可取的。你的批评同样适用于OP的问题。 - HoldOffHunger
向db-admin团队的成员展示a更不可取 假 错误信息,这是故意人为的,可能与发生的实际问题没有任何共同之处。 - Your Common Sense
你读过OP的帖子了吗? “我使用错误的连接数据来强制连接错误,但在现实世界中,数据库可能已关闭,或者网络可能已关闭......等等。“。拒绝访问不是唯一可能发生的错误。还有其他数千个错误。您的代码将为所有错误重复相同的消息。 - Your Common Sense
最后我终于明白了你的困惑。它基于“给我一个错误并立即停止脚本。“声明。要处理异常,如果您遇到特定错误的某种情况,则必须使用 try..catch 运算符,检查此特定错误,处理它,或者 - 如果错误是不同的,重新抛出异常让脚本立即死亡。您可以在此处找到示例: phpdelusions.net/pdo#errors - Your Common Sense