类“ Exception”的消息导致PHP致命错误

时间:2019-02-07 23:42:38

标签: php exception

执行以下简单代码后:

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

PHP返回致命错误

Fatal error</b>: in ...

此代码有望返回

Fatal error: Uncaught Exception: ..

但是这没有发生。出现此消息后,错误将在类“ Exception”中发生!

Code example 1 from sandbox.onlinephpfunctions.com(注释和取消注释2行代码3-4和6-7)

Code example 2 from sandbox.onlinephpfunctions.com

在转换许多其他IP时会注意到此行为。 目前,我在“ throw new”之前使用以下行解决了问题:

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

如何正确地将消息中的字符转义为Exception或PHP错误?

我的PHP版本是7.2

2 个答案:

答案 0 :(得分:1)

那是因为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中的错误。

答案 1 :(得分:0)

您使用inet_pton()的方法不正确,因为它是这样做的:

inet_pton — Converts a human readable IP address to its packed in_addr representation

您应该在不调用inet_pton()的情况下将地址附加到字符串中。

现在,关于错误。

我的所有PHP设置(从5.5.12到7.2.8)都不会发生该错误。 这是我从PHP 5.5.12得到的错误消息:

Fatal error: Uncaught exception 'Exception' with message 'some text wü!«' in C:\wamp\www\so\54584039.php:5 Stack trace: #0 {main} thrown in C:\wamp\www\so\54584039.php on line 5

我在其他版本中也遇到了同样的“未捕获的异常”错误,并得到https://3v4l.org/Klpep的确认。

这意味着该错误必须由对PHP设置中发生的Exception消息的后处理引起 但不会在3v4l.org的设置和我的操作中发生。

在我看来,可能的罪魁祸首是html_errors配置选项。 我将其设置为On来找出将要发生的事情,并且确实,我得到了您的错误:

<br />
<b>Fatal error</b>:   in <b>C:\wamp\www\so\54584039.php</b> on line <b>5</b><br />

因此,解决方案是将html_errors设置为Off

我强烈建议您始终将其设置为Off, 因为如果您使用的是JSON输出(或其他格式),则HTML格式无用,而且还会使错误消息更难以阅读。