【发布时间】: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\Exception或use 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