PHP 脚本导致分段错误,然后浏览器要求我下载其中没有任何内容的 .php 文件?

发布于 2024-08-24 07:04:45 字数 3539 浏览 3 评论 0原文

我注意到我的一些 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 将正确加载。但是,一旦我点击保存按钮(表单 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;
}

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(!$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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

无可置疑 2024-08-31 07:04:45

另外,请小心浏览器缓存。即使应用正确的设置和正确的文件处理程序,浏览器仍然提示下载文件。
这可以通过重新启动浏览器/清空浏览器缓存来解决。

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.

恋竹姑娘 2024-08-31 07:04:45

这可能是由于服务器配置不正确造成的。服务器直接发送文件,而不是将其解释为 PHP 程序。由于您使用的是 Apache,因此以下配置设置(从此处)应该解决问题:

<FilesMatch \.php
gt;
    SetHandler application/x-httpd-php
</FilesMatch>

编辑:似乎存在更深层次的问题。请参阅此答案下的评论和原始问题的评论。

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
gt;
    SetHandler application/x-httpd-php
</FilesMatch>

Edit: There appears to be a deeper problem. See comments under this answer and on the original question.

旧时模样 2024-08-31 07:04:45

这通常意味着您没有在服务器上正确安装或配置 PHP。

This typically means you do not have PHP installed or configured correctly on the server.

过期以后 2024-08-31 07:04:45

最终生成的 SQL 语句是什么样的?你在哪里:

// echo 'print this'; exit; 

如果你将其更改为:

echo "Query: $q";
exit;

并将结果发布到你的问题中......

据我所知,你的查询将如下所示:

INSERT some_table SET field1, field2, field3

何时应该:

INSERT INTO some_table SET field1='value 1', field2='value 2', field3='value 3'

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'
Spring初心 2024-08-31 07:04:45

我认为应该是
httpd.conf 中的 AddType application/x-httpd-php .php .phtml

我正在保存我的答案,因为这是一个修复,但他真正的问题是在 HTML 表单中使用“action”。
表单应该是:

<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>

您不在放置隐藏输入的表单操作中使用查询。我认为这就是它出现段错误的原因。如果您要保存数据,我不会使用“get”作为您应该使用“post”的方法。实际上我一直在使用“post”。

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.

画中仙 2024-08-31 07:04:45

如果您的 Apache 请求超时 小于php执行timeout 以及运行脚本所需的时间。

当 Apache 超时时,apache 会关闭连接。浏览器会看到连接完全关闭,但没有任何内容,因此无法识别如何处理它,因此通过询问您是否要保存文件,回到无法识别内容的默认行为。

取消注释“print this”echo 语句并退出会将一些文本输出到浏览器,而不是进入长时间运行的进程。未达到 Apache 超时,并且浏览器知道默认情况下应显示的内容。

如果脚本的处理时间不同,只是偶尔超过 apache 超时,则可以解释偶尔发生的情况。或者你的脚本可能在某个地方阻塞了。

如果脚本超时始终低于 apache 超时,您将收到信息更丰富的“致命错误:最大执行时间...”错误。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文