【问题标题】:Suppressing PDO Warnings抑制 PDO 警告
【发布时间】:2014-12-19 10:15:05
【问题描述】:

我正在尝试根据数据库是否可以连接来显示服务器状态。使用老派mysql_connect()mysqli_connect() 很容易。我试图保持现代,所以我使用 PDO,但我不知道如何抑制默认警告。据我所知,您需要使用 getMessage() 函数来打印 PDO 警告,但我没有使用它。

这是我的代码:

8  $dbstatus = 1;
9  try {
10  $db = new PDO($dbms . ':host=' . $dbhost . ';port=' . $dbport . ';dbname=' . $dbname, $dbuser, $dbpasswd);
11  $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
12 } catch(PDOException $e) {
13  $dbstatus = 0;
14 }
15 if($dbstatus == 1) {
16  echo '<span style="color: green">DB Up</span>';
17 } else {
18  echo '<span style="color: red">DB Down</span>';
19  exit;
20 }

所有连接变量均已提供且正确,但$dbhost 除外,为了测试而故意破坏了它。现在,它会产生所需的结果,但也会打印一条警告消息:

警告:PDO::__construct():php_network_getaddresses:getaddrinfo 失败:不知道这样的主机。在 C:\xampp\htdocs\cd\includes\dbconnect.php10

如果我更正了 $dbhost 变量,它工作正常,所以我知道问题不在于 PDO 语句可用。

关于我缺少什么的任何想法?

解决方案

我使用了 jeroen 提供的变体:

if(filter_var(gethostbyname($dbhost), FILTER_VALIDATE_IP)) {
 $dbstatus = 1;
 try {
  $db = new PDO($dbms . ':host=' . $dbhost . ';port=' . $dbport . ';dbname=' . $dbname, $dbuser, $dbpasswd, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
 } catch(PDOException $e) {
  $dbstatus = 0;
 }
} else {
 $dbstatus = 0;
}
if($dbstatus == 1) {
 echo '<span style="color: green">DB Up</span>';
} else {
 echo '<span style="color: red">DB Down</span>';
 exit;
}

感谢您的帮助,我希望这对其他人有帮助! ^^

【问题讨论】:

  • 在返回 json 的 ajax 调用中,警告(似乎无法捕获)使我最后两天的工作毫无用处。这很糟糕

标签: php mysql pdo exception-handling suppress-warnings


【解决方案1】:

我在这里唯一能看到的是,您告诉 PDO 在您尝试打开连接之后抛出异常。这很可能为时已晚。

您可以做的是直接使用第四个参数将该选项发送给构造函数:

try {
  $opts = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
  $db = new PDO($dbms . ':host=' . $dbhost . ';port=' . $dbport . ';dbname=' . $dbname,
                $dbuser, $dbpasswd, $opts);
} catch(PDOException $e) {
...

这可能会解决你的问题。

编辑:如果主机名由用户提供,您可以在将其发送到 PDO 构造函数之前对其进行验证。

例如使用:

if (filter_var(gethostbyname($user_provided_host_name), FILTER_VALIDATE_IP)) {
  // valid hostname / ip address
}

这适用于域名、localhost 和 IP 地址。

【讨论】:

  • 更改属性声明并不能阻止加载警告。
  • @AoN 奇怪,我没有测试完全一样,但我在这里得到了异常(使用 google.com 的 ip 地址...):codepad.viper-7.com/dLZi8R
  • 我想我知道它哪里出了问题。我通过在地址中间添加一个空格来断开连接,并且由此产生了错误。当我输入正确的域 (google.com) 或 IP 地址时,它不会产生警告。使用输入错误的“localhost”或 IP 会发出警告。这对于技术人员来说非常棒,但对于只想知道数据库是否已启动的用户来说则不然。反正知道要补偿这个吗?我在$dbhost 变量上尝试了rawurlencode(),但这对警告没有任何作用。 :S
  • @AoN 为避免您可能遇到的问题,您可以验证主机名,请参阅我的编辑。
  • if 语句中包装try catch 时仍然没有改变错误。