我从未在今天看过PHP中的SegFault,但显然它是可能的。起初我以为是mysql驱动程序,但事实证明这是我的代码;)。
我花了大约2天的时间来调试我的代码并最终跟踪它的原因(所以对于所有未来的PHP程序员来说,欢迎你们!)
长话短说,你 unset()
目的是消除$ this-> $ out数组中不存在的所有元素($ this->投票的键与$中某个元素的id属性匹配)出)。
我遇到的问题大约有一半时间代码运行正常,而另一半则会因apache日志中的分段错误而崩溃(因为它很难调试)有一段时间,直到我注意到这个错误。)
然而,这是一段非常糟糕的代码片段......
array_walk()
答案 0 :(得分:3)
根据我的理解,最终发生的事情是unset()
会弄乱$this->vote
的数组长度。 array_walk
使用一个迭代器,它希望$this->votes
数组在整个步行过程中保持相同的长度。如果我编写了自己的array_walk
函数(for ($i = 0; $i < count($this->votes); $i++
),它只会抛出一个未定义的索引通知。但由于我们使用array_walk
,它实际上会尝试查看内存中可能有或没有某些数据的位置。这可能导致函数的不可预测性(有时代码可以运行得很好,有时它会导致seg错误)。
所以做到这一点的正确方法是
$tmpVotes = array();
array_walk($this->votes, function(&$o, $key) use($that, $out, $tmpVotes) {
$found = array_filter($out, function($p) use($key, $that, $tmpVotes) {
return $p['id'] == $key;
});
if(count($found) > 0) {
$tpmVotes[$key] = $o;
}
});
$this->votes = $tmpVotes;
来自PHP手册:
只有数组的值可能会被更改;它的结构不能改变,即程序员不能添加,取消设置或重新排序元素。如果回调不符合此要求,则此函数的行为未定义且不可预测。
如果有人有更好的方法来解释这里发生的事情,请发帖!