我也在 stackoverflow.com 上发布了这个,因为我不确定这是编程问题还是服务器问题。我正在使用 ubuntu 9.10、apache2、mysql5 和 php5。
我注意到我的一些 php 程序有一个不寻常的问题。有时当访问像 profile.edit.php 这样的页面时,浏览器会抛出一个对话框,要求下载 profile.edit.php 页面。当我下载它时,文件中没有任何内容。profile.edit.php 应该是一个编辑用户信息的网络表单。
我在我的其他一些 php 页面上也注意到了这一点。我查看我的 apache 错误日志,并看到一条分段错误消息:
[Mon Mar 08 15:40:10 2010] [notice] child pid 480 exit signal Segmentation fault (11)
而且,问题可能会出现也可能不会出现,这取决于我部署应用程序的服务器。
附加细节 虽然这并不总是发生。它只是偶尔发生。例如,profile.edit.php 将正确加载。但只要我点击保存按钮(表单 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> </p>';
$this->arrBind = array();
return $stat;
}
由于无限递归,PHP 通常会出现段错误。如果是这种情况(尽管我在您发布的代码中没有看到任何内容),然后安装 XDebug 扩展,它添加了安全递归限制并会发出正常错误。
否则它可能是 PHP 本身的错误。尝试更新版本(您会在snaps.php.net上找到最先进的版本)