首页 > 解决方案 > 类“异常”的消息导致 PHP 致命错误

问题描述

执行此简单代码后:

$message = 'some text '.inet_pton('119.252.33.171');
throw new \Exception($message);

PHP 返回致命错误

Fatal error</b>: in ...

此代码预计会返回

Fatal error: Uncaught Exception: ..

但这并没有发生。使用此消息,错误发生在“异常”类中!

来自 sandbox.onlinephpfunctions.com 的代码示例 1(注释和取消注释 2 行代码 3-4 和 6-7)

来自 sandbox.onlinephpfunctions.com 的代码示例 2

转换许多其他 IP 时会注意到此行为。目前我在“抛出新”之前用以下行解决了这个问题:

$message = preg_replace( '/[^[:print:]\r\n]/', '_', $message);

如何正确转义消息中的字符以获取异常或 PHP 错误?

我的 PHP 版本是 7.2

标签: phpexception

解决方案


那是因为inet_pton()不是要输出字符串,而是按网络顺序输出字节(我不记得它是小端还是大端)。

异常消息不包括字节,而是可打印的字符。但是,您可以将纯字节放入字符串中。然后将它们解码为(可能)UTF-8 或其他编码以显示可读文本。

以下代码

$message = inet_pton('119.252.33.171');
var_dump($message);
for($i = 0; $i < strlen($message); $i++)
{
   echo ord($message[$i]) . "\n";
}

生产

string(4) "w�!�"
119
252
33
171

比较这两行

throw new \Exception(chr(33)); // Displays stacktrace
throw new \Exception(chr(252)); // Fails to output

我的猜测是当 PHP 尝试将字符串格式化为 UTF-8 以将异常消息打印到 stdout 时发生错误,但传入了无效的 UTF-8 字符串并且写入/解码失败。

无论哪种方式,似乎都是 PHP 中的错误。


推荐阅读