【问题标题】:Why PHP try... catch (Exception) does not catch exception raised by inconv() in Yii2 application?为什么 PHP try...catch (Exception) 不能捕获 Yii2 应用程序中 inconv() 引发的异常?
【发布时间】:2020-01-24 11:22:37
【问题描述】:

我有 PHP 代码(从 Yii2 应用程序运行):

    public static function convertNotes($notes) {
        if(is_null($notes)) {
            return $notes;
        }
        $tmp = 'Multibyte conversion error';
        try {
            $tmp = iconv('UTF-16LE', 'UTF-8', $notes); 
        } catch (Exception $ex) {
            $tmp = 'Multibyte conversion error: '+$ex->message;
        }
        return $tmp;
    }

代码尝试将 UTF16LE 字符串(来自数据库)转换为 UTF8 字符串。有时输入字符串不正确,它不是有效的 UTF16LE 字符串(字节序列)。在这种情况下会引发异常:

PHP Notice – yii\base\ErrorException
iconv(): Detected an incomplete multibyte character in input string 

没关系。但奇怪的是 - 即使我将 iconv() 全部包装到 try/catch 中,异常也不会被捕获,并且无论如何都会跳到顶层未被捕获。异常处理有什么问题?

【问题讨论】:

  • 如果你使用\Exception而不是Exception是否有效?
  • 确实,它也适用于 \ErrorException 或 \Exception 的任何变体。但将保留完整的 yii\base\ErrorException 以明确。
  • 这意味着Exception 被错误地解析,可能是app\controllers\Exception 而不仅仅是Exception。确保您在全局命名空间中(此文件中没有 namespace 关键字)并且您没有在此上下文中使用 Exception 名称(没有 use some\namespace\Exceptionuse some\namespace\SomeException as Exception)。
  • 您应该阅读命名空间的工作原理。 PHP 不会对您的项目的结构或使用的框架做出任何假设。所有非绝对 FQN 都被解析为相对于当前命名空间。所以app\models命名空间内的Exception将被解析为app\models\Exception。您需要使用绝对 FQN (\Exception) 或显式导入异常 (use Exception)。我真的很惊讶catch (yii\base\ErrorException $ex) 起作用了——它应该被解析为不存在的app\models\yii\base\ErrorException
  • 捕获像\Exception\Throwable 这样的通用异常是常见的事情,你不应该将你的应用程序绑定到Yii 太多。依赖与框架无关的接口通常可以减少迁移或框架/库更改的麻烦。

标签: php exception yii2 try-catch


【解决方案1】:

必须从 Yii 框架中捕获 ErrorException

try {
    $tmp = iconv('UTF-16LE', 'UTF-8', $notes); 
} catch (Exception $ex) {
    $tmp = 'Multibyte conversion error: '+$ex->message;
} catch (yii\base\ErrorException $ex) {
    $tmp = 'Multibyte conversion error (from Yii2): '.$ex->getName();
}

【讨论】:

  • 你可能有类似use yii\base\Exception; 的东西,多亏了你的第一个catch 只适用于扩展yii\base\Exception 而yii\base\ErrorExceptions 直接扩展\ErrorException 的异常。
猜你喜欢
  • 2021-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-21
  • 2011-05-27
  • 1970-01-01
  • 2023-03-29
  • 2013-12-05
相关资源
最近更新 更多