执行以下简单代码后:
$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
答案 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格式无用,而且还会使错误消息更难以阅读。