I've noticed an unusual problem with some of my php programs. Sometimes when visiting a page like profile.edit.php, the browser throws a dialogue box asking to download profile.edit.php page. When I download it, there's nothing in the file. profile.edit.php is supposed to be a web form that edits user information.
I've noticed this on some of my other php pages as well. I look in my apache error logs, and I see a segmentation fault message:
[Mon Mar 08 15:40:10 2010] [notice] child pid 480 exit signal Segmentation fault (11)
And also, the issue may or may not appear depending on which server I deploy my application too.
Additonal Details This doesn't happen all the time though. It only happens sometimes. For example, profile.edit.php will load properly. But as soon as I hit the save button (form action="profile.edit.php?save=true"), then the page asks me to download profile.edit.php. Could it be that sometimes my php scripts consume too much resources?
Sample code
Upon save action, my profile.edit.php includes a data_access_object.php file. I traced the code in data_access_object.php to this line here
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开发者_JAVA百科(!$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.
And if it helps, here's the function execute($sql) in data_access_object.php
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;
}
Also, be careful with browser caching. Even if applying the correct settings and the right file handler, the browser still prompt for a download of the file. This can be fixed by rebooting the browser/emptying the browser cache.
That is likely caused by incorrect server configuration. The server is sending the file directly, not interpreting it as a PHP program. Since you're using Apache, the following configuration setting (from here) should fix the problem:
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
Edit: There appears to be a deeper problem. See comments under this answer and on the original question.
This typically means you do not have PHP installed or configured correctly on the server.
What does the final SQL statement being generated look like? Where you have:
// echo 'print this'; exit;
What if you changed that to:
echo "Query: $q";
exit;
And posted the results in your question...
From what I can tell, your query will look like:
INSERT some_table SET field1, field2, field3
When it should be:
INSERT INTO some_table SET field1='value 1', field2='value 2', field3='value 3'
I think it should be
AddType application/x-httpd-php .php .phtml
in the httpd.conf
I'm saving my answer because it's a fix but his real problem is the use of "action" in the HTML form. The form should be:
<form action="myphpfile.php" method="get">
<input type="hidden" name="save" value="true" />
First name: <input type="text" name="firstname" /><br />
Last name: <input type="text" name="lastname" /><br />
<input type="submit" value="Submit" />
</form>
You don't use a query in the form action you place a hidden input. I think that is why it seg faults. I would not use "get" as the method you should use "post" if you are going to save data. I actually use "post" all the time.
This can happen if your Apache request timeout is less than than both the php execution timeout and the time required to run the script.
When the Apache timeout is reached, apache appears to close the connection. The browser sees the connection cleanly closed but does not have any content and so isn't able to recognise what to do with it, so falls back to the default behaviour for unrecognised content by asking you if you want to save the file.
Uncommenting your 'print this' echo statement and exiting outputs some text to the browser instead of entering the long running process. The Apache timeout is not reached, and the browser has content it knows it should display by default.
The occasional occurrence might be explained if the script varies in processing time, only occasionally exceeding the apache timeout. Or perhaps your script is blocking somewhere.
If the script timeout is always lower than the apache timeout, you'll get the more informative 'Fatal error: Maximum execution time...' error instead.
精彩评论