我们是否应该手动检查 mysqli_connect() 错误? [英] Should we ever check for mysqli_connect() errors manually?

查看:39
本文介绍了我们是否应该手动检查 mysqli_connect() 错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

mysqli_connect() 的 PHP 手册 建议检查返回值并在屏幕上显示错误消息.

$link = mysqli_connect("127.0.0.1", "my_user", "my_password", "my_db");如果(!$链接){echo "错误:无法连接到 MySQL.".PHP_EOL;回声调试错误号:".mysqli_connect_errno() .PHP_EOL;回声调试错误:".mysqli_connect_error() .PHP_EOL;出口;}

类似对于 OOP 风格的构造函数,建议这样做:

$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');如果 ($mysqli->connect_error) {die('连接错误(' . $mysqli->connect_errno . ') '.$mysqli->connect_error);}

Stack Overflow 上的一些用户甚至使用带有 mysqli_error($conn) 的代码,例如:

$conn = mysqli_connect('localhost', 'a', 'a');如果(!$con){die('无法连接:' .mysqli_error($conn));}

然而,在过去的几周里,我一直在问自己一个问题,我为什么需要这样做?第一个例子的输出是:

<块引用>

警告:mysqli_connect():(HY000/1045):用户访问被拒绝'my_user'@'localhost'(使用密码:YES)在C:xampp...mysqli.php 第 4 行

错误:无法连接到 MySQL.调试 errno: 1045 调试错误:用户my_user"@localhost"的访问被拒绝(使用密码:是)

如您所见,错误消息显示了两次!手动调试"实际上提供的信息较少.

我们是否应该手动检查连接错误?我们是否会以这种方式获得比自动警告更多的信息?这是推荐的做法吗?

解决方案

永远不要手动显示连接错误!

如果 MySQLi 无法打开与 MySQL 的连接,则会生成警告.此警告会告诉您所有您需要知道的信息,包括错误代码、错误消息以及代码中发生错误的位置.手动检查错误不会为您提供更多信息.

如果您看不到警告并且无法创建连接,则可能意味着您的 PHP 未配置为显示它们.在这种情况下,您必须检查服务器上的错误日志文件.如果您不知道那在哪里,请使用 phpinfo() 获取该信息并搜索 error_log.它会告诉您错误日志文件的位置.

如果错误日志中没有警告,则可能意味着您的 PHP 已停止错误报告(完全或只是警告).检查您的 PHP 配置.
生产环境中,应维护这些设置:

  • error_reporting 必须是 E_ALL
  • log_errors 必须 On
  • display_errors 必须Off

开发环境中,这些设置应该保持:

  • error_reporting 必须是 E_ALL
  • log_errors 必须 On
  • display_errors 必须 On

正如您在错误消息中看到的,您的数据库用户名和密码已透露给最终用户.这些是您不想向任何人显示的敏感信息.事实上,普通用户不会理解这个神秘的消息.这就是为什么在生产环境中必须始终关闭 display_errors 的原因.在服务器上记录错误是安全的.

警告与例外

警告不会停止脚本.如果发出警告,脚本将继续执行,直到遇到致命错误.在大多数情况下,您可能希望抛出异常来停止脚本.不要使用die/exit如果无法建立mysqli连接,应该抛出一个异常,如果没有处理它会冒泡并以致命错误停止脚本.您可以将 mysqli 配置为自动抛出异常.这是非常宝贵的,因为所有 mysqli 函数都可能由于多种原因而失败,并且除非您手动检查每个错误,否则它们不会通知您任何问题.在打开连接之前使用以下行:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');

除非您真的知道如何处理异常,否则不要捕获异常!如何使用 mysqli 正确连接

中描述了一种可能的用例

mysqli_error() 能否显示任何与连接相关的问题?

没有.mysqli_error($conn) 期望 mysqli 连接成功.$conn 必须是一个有效的 mysqli 连接,否则你会得到这个错误信息:

<块引用>

警告:mysqli_error(): 无法在 C:... 中获取 mysqli

$conn->errormysqli_error($conn) 都不能显示任何与连接相关的错误!


相关: 调用mysqli_stmt_prepare"时是否应该手动检查错误?>

The PHP manual for mysqli_connect() suggests checking for the return value and displaying the error messages on the screen.

$link = mysqli_connect("127.0.0.1", "my_user", "my_password", "my_db");
if (!$link) {
    echo "Error: Unable to connect to MySQL." . PHP_EOL;
    echo "Debugging errno: " . mysqli_connect_errno() . PHP_EOL;
    echo "Debugging error: " . mysqli_connect_error() . PHP_EOL;
    exit;
}

Similarly for OOP-style constructor this is suggested:

$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
if ($mysqli->connect_error) {
    die('Connect Error (' . $mysqli->connect_errno . ') '
            . $mysqli->connect_error);
}

Some users on Stack Overflow even used code with mysqli_error($conn) such as this:

$conn = mysqli_connect('localhost', 'a', 'a');
if (!$con) {
    die('Could not connect: ' . mysqli_error($conn));
}

However, in the past few weeks I have been asking myself a question, why would I need to do that? The output of the first example is:

Warning: mysqli_connect(): (HY000/1045): Access denied for user 'my_user'@'localhost' (using password: YES) in C:xampp...mysqli.php on line 4

Error: Unable to connect to MySQL. Debugging errno: 1045 Debugging error: Access denied for user 'my_user'@'localhost' (using password: YES)

As you can see the error message is displayed twice! The manual "debugging" actually provides less information.

Should we ever manually check for connection errors? Would we ever get more information this way than from the automatic warning? Is this the recommended practice?

解决方案

Never display connection errors manually!

MySQLi will generate a warning if it is unable to open the connection to MySQL. This warning tells you all you need to know including the error code, error message, and the place in the code where it happened. Checking for the error manually will not give you any more information.

If you can't see the warning and your connection cannot be created, it might mean that your PHP is not configured to show them. In that case, you must check the error log file on your server. If you do not know where that is, use phpinfo() to get that information and search for error_log. It will tell you where the error log file is located.

If there is no warning in the error logs, it could mean that your PHP has error reporting silenced (either completely or just warnings). Check your PHP configuration.
In the production environment these settings should be maintained:

  • error_reporting must be E_ALL
  • log_errors must be On
  • display_errors must be Off

In the development environment these settings should be maintained:

  • error_reporting must be E_ALL
  • log_errors must be On
  • display_errors must be On

As you can see in the error message your database username and password has been revealed to the end-user. These are sensitive information which you do not want to show anyone. In fact, a normal user would not understand this cryptic message. This is why display_errors must always be switched off in the production environment. Logging the errors on the server is safe.

Warnings vs. Exceptions

Warnings do not stop the script. If a warning is emitted the script will keep on executing until it encounters a fatal error. In most cases, you would want to throw an exception to stop the script. Do not use die/exit! If mysqli connection cannot be made, an exception should be thrown and if it is unhandled it will bubble up and stop the script with a fatal error. You can configure mysqli to throw exceptions automatically. This is invaluable because all mysqli functions can fail for many reasons and they will not inform you about any problems unless you check for errors manually every single one of them. Use the following line before opening connection:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');

Do not catch the exceptions unless you really know what to do with them! One possible use case is described in How to connect properly using mysqli

Can mysqli_error() show any connection-related problems?

No. mysqli_error($conn) expects that the mysqli connection was successful. $conn must be a valid mysqli connection otherwise you would get this error message:

Warning: mysqli_error(): Couldn't fetch mysqli in C:...

Neither $conn->error nor mysqli_error($conn) can display any connection related errors!


Related: Should I manually check for errors when calling "mysqli_stmt_prepare"?

这篇关于我们是否应该手动检查 mysqli_connect() 错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆