【问题标题】:set_exception_handler Not Catching Class Exceptionsset_exception_handler 未捕获类异常
【发布时间】:2021-09-27 15:58:01
【问题描述】:

我在这里和一般情况下进行了很多搜索,并且在发布之前已经尝试了我能想到的一切,但我无法弄清楚这一点。我敢肯定,一个体面的 php 人会立即知道问题所在,所以...

我有一个文件Db.php,其中包含abstract class Db,其中包含require_once Config.php

Config.php 包括:

function global_exception_handler($e) {
    mail(ADDR_TO, "Error", "ERROR: $e", "From: ".ADDR_FM);
}

set_exception_handler('global_exception_handler');

:: 如果我从 Config.php 中的代码下方抛出异常 - 例如,throw new Exception("Test");,它会起作用(收到电子邮件)。

:: 如果我在 Db.php 中抛出异常在 Db 类之外,它会起作用。

:: 但是如果我从 Db 类中抛出一个异常 - 例如在我执行连接测试的构造函数中 - 什么也不会发生。

即使我将 global_exception_handler 函数和 set_exception_handler 声明移动到 Db 类(使用类形式 @set_exception_handler(array($this, 'global_exception_handler'))),它也不会触发。

我知道我肯定遗漏了一些明显的东西,尽管我几乎可以肯定这在 Hostgator 将我们的服务器从 php 5.5 升级到 7.4 之前可以正常工作。


回答@WesselvanderLinden 的问题和代码请求...

  1. (非常简单的)Db 类构造函数代码正在执行,并且只执行一次;我根据错误处理程序在其中添加了跟踪mail警报以对此进行测试。

  2. 构造函数最初有一个Try...Catch,我在几条内务声明之后在Catch 中抛出了异常。我删除了所有的“噪音”,并将构造函数简化为简单的。

  3. Config.php 文件包含在 Db.php 文件中 (require_once),处理程序语句如上所示。

这是基本的 Db 类构造函数代码(带有注释的运行检查跟踪电子邮件):

require_once "Config.php";

abstract class Db {

    public function __construct() {
        //mail(ADDR_TO, "Database Error", "ERROR!", "From: ".ADDR_FM);
        throw new Exception("Database connection failed");
    }
}

【问题讨论】:

  • 这里可能会发生一些事情。抽象类的构造函数可能会被覆盖,因此构造函数中的代码不会执行。也许某处有一个 try-catch,或者顺序错误(例如,您首先抛出异常,然后设置异常处理程序)。所以我认为你应该添加更多的代码,这样我们就可以看到发生了什么。为您的构造函数添加代码,也许还可以添加 DB 类的示例实现。否则有点难以回答:)
  • @WesselvanderLinden 我会补充这个问题,谢谢。
  • 请发布一个完整的最小示例。
  • 问几个问题:你为什么使用abstract class?是否有子类扩展类Db?你如何实例化Db 类?
  • @wayneOS 是的,Db 类扩展为其他基于 Db 的类,例如Db_AdminDb_Client 等。所以Db 本身没有被实例化。

标签: php php-7


【解决方案1】:

好的,这是完整的代码,可以复制和粘贴了。我已经在 docker 机器上的 PHP 7.4.15 上运行了它,它做了它应该做的事情。 我还在 http://phptester.net/ 上运行了各种其他 PHP 版本,并且输出始终相同...

无法重现您的问题。

echo 'PHP '.phpversion().PHP_EOL;

function global_exception_handler($e) {
    echo 'exception handler : ' . $e->getMessage() . PHP_EOL;
}

abstract class Db {

    public function __construct() {
        //mail(ADDR_TO, "Database Error", "ERROR!", "From: ".ADDR_FM);
        throw new Exception("Database connection failed");
    }
}
class Db2 extends Db {
    
}

set_exception_handler('global_exception_handler');


$db = new Db2();

此代码在我的 docker 机器上的输出:

PHP 7.4.15
exception handler : Database connection failed

【讨论】:

  • 如问题中所述,Db.php 包括Config.php(如require_once),其中我设置了全局处理程序。 Config.php 具有处理函数和 set_exception_handler 声明。我不知道怎么做,但这会造成任何问题吗?
【解决方案2】:

让我们看看

我创建了Config.php

<?php
function global_exception_handler($e) {
    echo ADDR_TO, "Error", "ERROR: $e", "From: ".ADDR_FM;
}
set_exception_handler('global_exception_handler');
?>

然后index.php;

<?php
require_once "Config.php";
const ADDR_TO = "to@example.com";
const ADDR_FM = "from@example.com";

abstract class Db {
    public function __construct() {
        throw new Exception("Database connection failed");
    }
}

class MyDb extends Db {}

$db = new MyDB(); // run construct
?>

当我运行它时,我会得到一个输出:

to@example.comErrorERROR: Exception: Database connection failed in /home/daniil/.../index.php:10
Stack trace:
#0 /home/daniil/.../index.php(19): Db->__construct()
#1 {main}From: from@example.com

如你所愿

【讨论】:

    猜你喜欢
    • 2013-07-19
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 2012-05-31
    相关资源
    最近更新 更多