1 回答
TA贡献1827条经验 获得超8个赞
看来您误解了错误报告的概念。我将尝试向您阐明一般概念。
错误报告是为了通知开发人员错误的编码、错误和其他需要修复的潜在问题。错误报告不适用于该产品的用户。当你在开发时,你可以display_errors为自己启用,但你不应该将它留在代码中。但是,您应该始终记录错误。PHP 有一个非常好的错误记录器,但我能理解它对您来说可能不够用,并且您想记录更多信息和错误消息。
您可以编写通用错误处理程序并捕获应用程序抛出的所有错误和异常,并使用您自己的记录器软件将其记录到服务器上的安全位置。不要在代码中间捕获异常。这样的记录器需要是您的应用程序的核心,并且在一个单独的文件中,以便能够捕获所有错误。
出于这个原因,您的 try-catch 不是很有用,因为您将它放在多个地方并且它与您的应用程序代码交织在一起。此外,您只捕获异常并忽略错误。你应该抓住两者。使用类似的东西catch(\Throwable $e)来捕捉两者。
@是错误抑制运算符。应该不惜一切代价避免它。如果你不能避免它,那么你需要重写代码来避免它。你在那里用 mysqli 连接做什么你实际上忽略了错误两次。首先,您使用@然后杀死您的脚本。不要杀死脚本。不要沉默错误。让你的错误冒出来,让它们被你的错误处理程序捕获。
如果你仔细想想,你的课ConnectDB是很没用的。要连接到数据库,您始终需要相同的 3 行。mysqli 已经是一个类,所以在另一个类中包装 3 行是没有意义的。正确的代码应该无外乎:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$conn = new mysqli(DB_HOST, DB_USERRW, DB_PASSWRW, DB_DBASE);
$conn->set_charset('utf8mb4');
当 mysqli 无法连接时,您当前的脚本会退出,但即使您没有消除错误并且打开了错误报告,变量也不可能为空。if(!$this->db)成为另一个谬误。此外,当您刚刚将一个异常静音时,为什么要抛出异常?这让我想到了另一点。为什么在立即捕获时抛出异常?当然,整个逻辑无非就是一个简单的 if 语句:
if(!$this->db) {
$this->messager->erroutput([' Database connection is currently unavailable.']);
}
我看到你已经命名了你的类MessageOut,我真的希望你不要将错误消息暴露给用户。这不仅是糟糕的用户体验,而且还有安全风险。您应该改为实现一个漂亮的 HTTP 500 错误页面,或者如果您的应用程序足够复杂,您自己的错误页面将在您的错误处理程序捕获到错误时显示。
一旦发现错误就关闭 mysqli 错误报告是没有用的。mysqli_report(MYSQLI_REPORT_OFF);只需从您的代码中删除。
要形象化我所描述的内容,请考虑以下代码:
<?php
// ini_set('display_errors', 1);
ini_set('log_errors', 1);
error_reporting(E_ALL);
class WebApp {
protected $db;
function __construct() {
$this->messager = new MessageOut();
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); // it can also be at the top of the script, but it makes more sense to put it together with the rest of mysqli code
$this->db = new \mysqli(DB_HOST, DB_USERRW, DB_PASSWRW, DB_DBASE);
$this->db->set_charset('utf8mb4');
}
public function selectIdata() {
//select data
$query = "SELECT *
FROM thetable";
$stmt = $this->db->prepare($query);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($idata);
$result = [];
while ($stmt->fetch()) {
$result[] = $idata;
}
return $result;
}
}
try {
$app = new \WebApp();
} catch (\Throwable $e) {
// log your errors here.
}
它不是完美的代码,因为错误处理程序不在那里,它也应该在一个单独的文件中,但总体思路是避免应用程序逻辑中不必要的代码。不要尝试捕捉。不要消除错误,也不要添加无用的代码。把事情简单化。
- 1 回答
- 0 关注
- 108 浏览
添加回答
举报