如何排除导致段错误的 PHP 脚本?

如何排除导致段错误的 PHP 脚本?

我也在 stackoverflow.com 上发布了此问题,因为我不确定这是编程问题还是服务器问题。我使用的是 ubuntu 9.10、apache2、mysql5 和 php5。

我注意到我的一些 php 程序存在一个不寻常的问题。有时在访问 profile.edit.php 之类的页面时,浏览器会弹出一个对话框,要求下载 profile.edit.php 页面。当我下载它时,文件中没有任何内容。profile.edit.php 应该是编辑用户信息的 Web 表单。

我也注意到我的其他一些 php 页面上也存在这种情况。我查看了我的 apache 错误日志,看到了一个段错误消息:

[Mon Mar 08 15:40:10 2010] [notice] child pid 480 exit signal Segmentation fault (11)

此外,该问题可能会出现,也可能不会出现,这取决于我在哪台服务器上部署我的应用程序。

更多详细信息 不过这种情况并不是总是发生。它只是偶尔发生。例如,profile.edit.php 可以正确加载。但是,只要我点击保存按钮(form action="profile.edit.php?save=true"),页面就会要求我下载 profile.edit.php。是不是我的 php 脚本有时消耗了太多资源?

示例代码

保存操作后,我的 profile.edit.php 包含一个 data_access_object.php 文件。我将 data_access_object.php 中的代码跟踪到此处的这一行

 if($params[$this->primaryKey])
 {
                        $q = "UPDATE $this->tableName SET ".implode(', ', $fields)." WHERE ".$this->primaryKey." = ?$this->primaryKey";
                        $this->bind($this->primaryKey, $params[$this->primaryKey], $this->tblFields[$this->primaryKey]['mysqlitype']);
}
 else
{
$q = "INSERT $this->tableName SET ".implode(', ', $fields);
}
// Code executes perfectly up to this point
// echo 'print this'; exit; // if i uncomment this line, profile.edit.php will actually show 'print this'.  If I leave it commented, the browser will ask me to download profile.edit.php
if(!$this->execute($q)){ $this->errorSave = -3; return false;}
// When I jumped into the function execute(), every line executed as expected, right up to the return statement.  

如果有帮助的话,这里是 data_access_object.php 中的函数 execute($sql)

function execute($sql)
{

        // find all list types and explode them
        // eg. turn ?listId into ?listId0,?listId1,?listId2 
        $arrListParam = array_bubble_up('arrayName', $this->arrBind);

        foreach($arrListParam as $listName)
           if($listName)
           {
                $explodeParam = array();
                $arrList = $this->arrBind[$listName]['value'];
                foreach($arrList as $key=>$val)
                {
                        $newParamName = $listName.$key;
                        $this->bind($newParamName,$val,$this->arrBind[$listName]['type']);
                        $explodeParam[] = '?'.$newParamName;
                }
                $sql = str_replace("?$listName", implode(',',$explodeParam), $sql);
           }

        // replace all ?varName with ? for syntax compliance
        $sqlParsed = preg_replace('/\?[\w\d_\.]+/', '?', $sql);
        $this->stmt->prepare($sqlParsed);

        // grab all the parameters from the sql to create bind conditions
        preg_match_all('/\?[\w\d_\.]+/', $sql, $matches);
        $matches = $matches[0];

        // store bind conditions
        $types = ''; $params = array();
        foreach($matches as $paramName)
        {
                $types .= $this->arrBind[str_replace('?', '', $paramName)]['type'];
                $params[] = $this->arrBind[str_replace('?', '', $paramName)]['value'];
        }

        $input = array('types'=>$types) + $params;



        // bind it
        if(!empty($types))
        call_user_func_array(array($this->stmt, 'bind_param'), $input);

        $stat = $this->stmt->execute();
        if($GLOBALS['DEBUG_SQL'])
                echo '<p style="font-weight:bold;">SQL error after execution:</p> ' . $this->stmt->error.'<p>&nbsp;</p>';

        $this->arrBind = array();
        return $stat;
}

答案1

PHP 通常因无限递归而导致分段错误。如果是这种情况(尽管我没有在您发布的代码中看到任何这种情况),则安装 XDebug 扩展,它会添加安全递归限制并发出正常错误。

否则,PHP 本身可能存在错误。尝试较新的版本(您可以在snaps.php.net

相关内容