为什么当 mysqli_connect 失败时 PHP 不显示我的自定义错误消息?

Kis*_*ane 4 php mysql mysqli

我正在尝试连接到数据库,当我尝试一切正确时,数据库会连接,一切都很好。但是,当我尝试使用一些错误的凭据进行连接时,它会抛出一条错误消息,我正在想办法向用户隐藏错误消息。

function connectDatabase(){
        $dbServerName = 'local_host';
        $dbUsername = 'root';
        $dbPassword = '';
        $dbName = 'kishor_me';

        $conn = mysqli_connect($dbServerName, $dbUsername, $dbPassword, $dbName);
        
        if (!$conn) {
            echo "error message";
        }else{
            echo "success message";
        }
    }
Run Code Online (Sandbox Code Playgroud)

是否有任何方法可以向用户显示严重错误消息,而不是该语言生成的其他错误描述,并且不给出 HTTP 500 错误?如果有什么办法或者这个问题是否已经得到解答,请告诉我。

You*_*nse 5

您似乎正在使用一些过时的教程,该教程提供了报告错误的错误方法:尝试手动检测连接错误并自行输出某些内容的代码。但是你的代码不应该做这样的事情:PDO 和 mysqli 都可以自动引发错误,而且,你的代码的这一部分永远不应该自己与用户对话

让我们逐步回答您的问题:

如何检测连接错误

在远古时代,大约10年前,PHP使用mysql扩展与MySQL数据库对话,MySQL数据库无法自动处理错误,每次数据库操作都必须手动检查错误。这就是这些if (!$conn) {东西的来源。但这个 ext 早已不复存在,PHP 有了一个新的,mysqli。它能够自动引发错误,就像 PHP 中的任何其他命令include一样header()。您不会手动检查每个include结果header(),是吗?所以你不应该使用 mysqli 或 PDO。

正如您所看到的,mysqli_connect()(以及new mysqli()new PDO())会自动生成错误,就像任何其他 PHP 函数一样。所以这部分没有任何用处if (!$conn) {。既不在连接上,也不在query()任何其他数据库功能上。

简而言之:您不需要任何代码来检测数据库错误。现在它们已成为常规错误。而且,如果您想一想,不仅需要隐藏数据库错误。任何其他错误,例如“标头已发送”或“没有此类文件或目录”也必须对站点用户隐藏。

所以现在的问题更加普遍:

如何对站点用户隐藏所有错误消息

要向站点用户隐藏错误消息,您必须使用专门用于此目的的配置选项:display errors。当设置为 时0,它将阻止 PHP 显示发生的任何错误。最好在 PHP 代码中进行设置,php.ini但如果您无法控制 PHP 配置,至少可以在 PHP 代码中进行设置:

ini_set('display_errors', 0);
Run Code Online (Sandbox Code Playgroud)

最棒的部分是,这只是一个设置的地方。因此,在本地 PC 或测试服务器上,您可以将其设置为 1 并在线查看所有错误。同样,无需对代码进行任何更改:如您所见,失败的连接尝试已经提供了详细的错误消息,但没有这些if (!$conn) {内容。但在实时服务器上,display errors必须设置为 0,这样就不会向用户泄露任何错误消息,而log_errors必须设置为 1。遗憾的是,这是一个简单的规则,但在书籍或教程中很少提及。顺便说一句,我推荐 Jon Duckett 写的《PHP&MySQL》一书,其中详细解释了这种方法。

连接凭证

即使不显示凭据,当敏感信息被记录时,有些人也会感到不安。更新您的 PHP 版本。从 8.2 开始,它从堆栈跟踪中隐藏数据库密码。

如何处理连接错误

如果您想测试凭据,例如在运行安装脚本时,您可以将连接包装在 try..catch 中。但你不应该在生产代码中这样做。或者,如果您有连接失败时的备份场景,您也可以将连接包装在 try..catch 中。简而言之,如果您有处理场景而不只是报告错误,请使用 try..catch,在这种情况下,只需保留连接代码即可。

因此,唯一的问题是“如何向用户显示严重错误消息?”。

如何向网站用户显示漂亮的错误页面

只需配置一个错误处理程序即可。这是我关于PHP 错误报告的文章中的一篇:

set_exception_handler(function ($e)
{
    error_log($e);
    http_response_code(500);
    if (ini_get('display_errors')) {
        echo $e;
    } else {
        echo "<h1>500 Internal Server Error</h1>
              An internal server error has been occurred.<br>
              Please try again later.";
    }
});
Run Code Online (Sandbox Code Playgroud)

根据display_errors值,它将显示错误本身,或者仅显示一般消息。


请注意,它“给出了 HTTP 500 错误”,这与您的请求相反,实际上是必须执行的操作。当您的页面由于服务器错误而无法提供实际内容时,它必须使用 5xx HTTP 代码进行响应。