php mysqli 异常会忽略大量 catch 块,直到最后一个(在任何类之外)

问题描述 投票:0回答:1

我有一个mysqli调用(

$result = $this->mysqli->query($query)
),其中
$query
是一个生成错误的插入语句:“重复条目'dt'键'username_UNIQUE'”;。 我已经设置了 mysqli 报告模式

\mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

此时的调用堆栈大约有 8 个方法深,并且沿途有几个 try-catch 块。

最后,index.php 中有一个 try-catch 块,即最外层的代码块。该异常似乎忽略了所有较深的 try-catch 块,但在最外层的块中被捕获。不确定这是否重要,但除了 index.php 中的代码之外,所有代码块都在类方法中。

为了演示这个问题,我将向您展示index.php 和从index.php 调用的第一个方法。

<?php
    define('DS',DIRECTORY_SEPARATOR);
    define('APP_START',microtime(true));
    define('ROOT_DIR',dirname(__FILE__).DS);
    define('FW_DIR',sprintf("%svendor%sfw%s",ROOT_DIR,DS,DS));
    define('APP_DIR',sprintf( '%sapp%s',ROOT_DIR,DS));
    try {
        // set up the autoloader
        require sprintf('%sbootstrap%sbootstrap.php',FW_DIR,DS);
        // next, set up the factory for all future class instantiation
        $factory = new fw\factory\ClassFactory();
        // create the app
        $app = $factory->getClass('app\app');
        // process the request
        $ob = "";
        $result = $app->go();
        // return anything in the output buffer then the application output
        echo $ob.$result;
    } catch (Exception $e) {
        die("Caught Exception in index.php: ".$e->getMessage());
    }

我确定上面的代码执行到

$app->go()
,但没有到达
echo $ob.$result;
行。

现在这是 $app 类:

<?php
namespace app;
class App extends \fw\app\App
{
    protected $trace = false;
    public function __construct(protected \fw\exception\ErrorHandler $errorhandler,
                                protected \fw\session\WebSession $session,
                                protected \app\http\RequestHandler $requesthandler,
                                protected \database\MySqlDB $db
                                ) {
        parent::__construct();
    }
    public function go(){
        try {
            $this->requesthandler->init($this->errorhandler,$this->session,$this->db);
            $result = $this->requesthandler->processrequest(false);
        } catch (Exception $e) {
            die(__METHOD__." : ".$e->__toString());
        }
        return $result;
    }
}

我确定代码输入了

$this->requesthandler->processrequest(false);
。 许多方法调用更深,它到达触发异常的插入语句。

上面的输出是“在index.php中捕获异常:键'username_UNIQUE'的重复条目'dt'”,这显然来自index.php中的catch。我的问题是,为什么代码没有死在 $app 类的 catch 块中(或堆栈中更深的任何其他 try-catch)。

php exception mysqli try-catch
1个回答
0
投票

您的

App
班级被指定使用

namespace app;

这意味着将在其中查找引用的类

namespace
。因此,你的

try {
    //some code
} catch (Exception $e) {
    //some code
}

将捕获

Exception
命名空间内的任何
app
对象,即任何可能抛出的
\app\Exception
。引发的实际异常是
\Exception
的实例,因此它不会被您拥有的
catch
捕获。你可以有

} catch (\Exception $e) {

例如,这是您想要捕获其实例的

Exception
类的完整命名空间名称。

查看别名和导入以及命名空间以获取更多信息。

© www.soinside.com 2019 - 2024. All rights reserved.