PHP json_encode a debug_backtrace() 与资源类型
目前,我有一个记录器,它将错误和回溯记录在一起。 记录器通过 json_encode() 将回溯序列化为 JSON。
让我们看一些假设的代码...
<?php
error_reporting(-1); // show all errors
function test($b){
echo json_encode(debug_backtrace()); // take a backtrace snapshot
}
$c = imagecreate(50,50); // create a resource...
test($c); // ...and pass to function
?>
如果您运行上面的代码,我们会看到类似的内容:
警告: json_encode() [function.json-encode]:第 5 行 /code/ch6gVw 中的 类型不受支持,编码为 null [{"file":"/code/ch6gVw","line":8,"function":"test","args":[null]}]
我们可以注意到这里发生了两件事:
- 记录器本身导致警告!坏坏坏!
- 记录的数据告诉我们我们向函数传递了一个空值?!?!
所以,我提出的解决方案类似于:
foreach($trace as $i=>$v)
if(is_resource($v))
$trace[$i] = (string)$v.' ('.get_resource_type($v).')';
结果看起来像Resource id #1 (gd)
但是,这可能会导致一些严重的问题。 我们需要以某种
- 方式跟踪我们循环遍历的数组,以避免陷入无限循环,数组引用自身(
$GLOBALS
往往会导致这种混乱)。 - 我们还必须转换对象属性的资源,但与数组不同,对象不是原始对象的副本,因此更改属性会更改活动对象。另一方面,
clone()
对象的安全性如何? - 这样的循环不会严重减慢服务器速度(回溯往往很大,不是)?
Currently, I have a logger which logs errors together with a backtrace.
The logger serializes the backtrace to JSON via json_encode()
.
Let's look at some hypothetical code...
<?php
error_reporting(-1); // show all errors
function test($b){
echo json_encode(debug_backtrace()); // take a backtrace snapshot
}
$c = imagecreate(50,50); // create a resource...
test($c); // ...and pass to function
?>
If you run the code above, we will see something like:
Warning: json_encode() [function.json-encode]: type is unsupported, encoded as null in /code/ch6gVw on line 5
[{"file":"/code/ch6gVw","line":8,"function":"test","args":[null]}]
We can notice two things going on here:
- The logger itself is causing a warning! Bad bad bad!
- The logged data tells us we passed a null to the function?!?!
So, my proposed solution is something like:
foreach($trace as $i=>$v)
if(is_resource($v))
$trace[$i] = (string)$v.' ('.get_resource_type($v).')';
The result would look like Resource id #1 (gd)
This, however, may cause some grave issues.
- We need to somehow track which arrays we looped through so as to avoid ending up in infinite loops with arrays referencing themselves (
$GLOBALS
tend to cause this mess). - We would also have to convert resources of object properties, but objects, unlike arrays, are not a copy of the original thing, hence changing the property changes the live object. On the other hand, how safe is it to
clone()
the object? - Won't such a loop severely slow down the server (backtraces tend to be large, no)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我最终得到了以下函数:
您可以在此处查看它的运行情况。但是,我不相信:
$a = array(); $a['ref'] = &$a;
(PHP 对某些内部变量执行此操作)__clone( )
,邀请破坏)。I ended up with the following function:
You can see it in action here. However, I'm not convinced:
$a = array(); $a['ref'] = &$a;
(PHP does this to some internal variables)__clone()
, an invitation to wreck havoc).那么您正在尝试将回溯存储为一种数据结构,以便稍后可以用来漂亮地打印结果?
如果不需要,我只需存储
$result = print_r(debug_backtrace(), true)
并完成它。如果不是,我的第一个镜头将是这样的:
这只是一个粗略的草图,但我不知道有任何项目以非文本或已处理的格式存储回溯以供以后检查,并且环顾成熟的框架并没有提出任何建议
So you are trying to store the backtrace as a data structure that can be used to pretty-print the results later on?
If that isn't needed I'd just store
$result = print_r(debug_backtrace(), true)
and be done with it.If not my first shot would be something like:
It's just a rough sketch but I'm not aware of any project that stores backtracks for later inspection in a non textual or already processed format and looking around the mature frameworks didn't bring anything up