为什么我在PHP中遇到分段错误?

时间:2013-02-07 21:15:41

标签: php arrays segmentation-fault

我从未在今天看过PHP中的SegFault,但显然它是可能的。起初我以为是mysql驱动程序,但事实证明这是我的代码;)。

我花了大约2天的时间来调试我的代码并最终跟踪它的原因(所以对于所有未来的PHP程序员来说,欢迎你们!)

长话短说,你 unset()

目的是消除$ this-> $ out数组中不存在的所有元素($ this->投票的键与$中某个元素的id属性匹配)出)。

我遇到的问题大约有一半时间代码运行正常,而另一半则会因apache日志中的分段错误而崩溃(因为它很难调试)有一段时间,直到我注意到这个错误。)

然而,这是一段非常糟糕的代码片段......

array_walk()

1 个答案:

答案 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手册:

  

只有数组的值可能会被更改;它的结构不能改变,即程序员不能添加,取消设置或重新排序元素。如果回调不符合此要求,则此函数的行为未定义且不可预测。

如果有人有更好的方法来解释这里发生的事情,请发帖!