首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >PHP Apache在执行存储过程时崩溃

PHP Apache在执行存储过程时崩溃
EN

Stack Overflow用户
提问于 2015-07-08 05:45:41
回答 6查看 1.3K关注 0票数 22

问题

当我执行以下代码时(我使用5个IN参数和1个OUT参数调用一个存储过程)

代码语言:javascript
复制
$conn->query("SET @res = ''");

$mysqli=$conn;
if (!($stmt = $mysqli->prepare("CALL retrieve_matches(5,3, 16, 2, false, @res)"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

do {
    if ($res = $stmt->get_result()) { //Apache crash on this call
        printf("---\n");
        var_dump(mysqli_fetch_all($res));
        mysqli_free_result($res);
    } else {
        if ($stmt->errno) {
            echo "Store failed: (" . $stmt->errno . ") " . $stmt->error;
        }
    }
} while ($stmt->more_results() && $stmt->next_result());

apache正在崩溃,出现错误:

AH00428:父进程:子进程9628退出,状态为255 --正在重新启动。

我尝试过的

  1. 此代码运行正常,并正确返回结果:

代码语言:javascript
复制
$conn->query("SET @res = ''");
$res=$conn->query("CALL retrieve_matches(5,3, 16, 2, false, @res)");
var_dump($res->fetch_assoc());

注释:如果我只需更改存储过程输入中的数字,上面使Apache崩溃的相同代码就可以正常工作:

代码语言:javascript
复制
if (!($stmt = $mysqli->prepare("CALL retrieve_matches(5,6, 16, 2, false, @res)"))) {

  1. 尝试在MySQl工作台上运行,两个调用都工作正常。
  2. 我在WIN7企业版64b上使用WAMP 64b,我尝试使用WAMP 32b,但得到了同样的问题。
  3. 我检查了windows事件,我发现httpd.exe崩溃是由WAMP引起的。你可以在谷歌上搜索"httpd.exe php5ts.dll“,你可以找到很多人在解决这个问题。但是我没有找到使用AMPPS的WAMP...
  4. Tried的解决方案,完全相同的问题

PHP错误日志

代码语言:javascript
复制
[10-Jul-2015 15:30:03 UTC] PHP Warning:  PHP Startup: Unable to load dynamic library 'C:/Program Files/wamp/bin/php/php5.5.12/ext/php_ldap.dll' - Impossibile trovare il modulo specificato.

 in Unknown on line 0

[10-Jul-2015 15:30:04 UTC] PHP Warning:  PHP Startup: Unable to load dynamic library 'C:/Program Files/wamp/bin/php/php5.5.12/ext/php_intl.dll' - Impossibile trovare il modulo specificato.

APACHE错误日志:

代码语言:javascript
复制
[Tue Jul 14 15:02:13.038276 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00428: Parent: child process 9448 exited with status 255 -- Restarting.
[Tue Jul 14 15:02:13.324305 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00455: Apache/2.4.9 (Win32) PHP/5.5.12 configured -- resuming normal operations
[Tue Jul 14 15:02:13.329306 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00456: Apache Lounge VC11 Server built: Mar 16 2014 12:13:13
[Tue Jul 14 15:02:13.329306 2015] [core:notice] [pid 7044:tid 404] AH00094: Command line: 'C:\\Program Files\\wamp\\bin\\apache\\apache2.4.9\\bin\\httpd.exe -d C:/Program Files/wamp/bin/apache/apache2.4.9'
[Tue Jul 14 15:02:13.352308 2015] [mpm_winnt:notice] [pid 7044:tid 404] AH00418: Parent: Created child process 3140
[Tue Jul 14 15:02:14.528388 2015] [mpm_winnt:notice] [pid 3140:tid 332] AH00354: Child: Starting 64 worker threads.

我真的迷路了,我该去哪里找问题呢?非常感谢你的帮助

编辑

我意识到存储过程"retrieve_matches“在更改后的值的函数中调用不同的存储过程。我调试了使Apache崩溃的存储过程"retrieve_standalone“。此过程正在执行select/ insert,我检查并正确执行了insert。但在"retrieve_standalone“中,我以一种奇怪的方式使用游标:

代码语言:javascript
复制
declare bNoMoreRows bool default false;
declare tmp_cursor cursor for
    select comp_id from to_match; -- to_match is a temporary table
declare continue handler for not found set bNoMoreRows := true;

如果我没有打开光标

代码语言:javascript
复制
open tmp_cursor;

一切都很正常!!所以我想我找到了问题所在:我该如何解决它?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2015-07-17 18:46:23

显然,在PHP开发者和MySQLi开发者之间有一些推卸责任的行为。

似乎正在发生的事情是,MySQLi以一种“不正确”的方式做出反应,并返回一个意想不到的值(我敢打赌它是一个空值),它会适时地进行核心转储。这种行为和来自PHPland的结论是:“不是is documented错误”。在他们这边,MySQLi人员坚持认为是PHP没有正确地检查返回的结果。无论如何,“不恰当”的结果取决于你的查询。

所以我冒了个险,假设你的问题和“通信困难”是一样的,所以问题变成了:“你的查询强制MySQLi放弃/重新连接”。为什么会这样呢?显然(有些)存储过程是require mysqli_multi_query in order to behave properly的。

而且mysqli_multi_querymysqli_prepare不兼容。

因此,我建议在不准备查询的情况下尝试,并使用mysqli_multi_query运行它。

代码语言:javascript
复制
$conn->query("SET @res = ''");
$conn->multi_query("CALL retrieve_matches(5,3, 16, 2, false, @res)");

do {
    if ($result = $conn->store_result()) {
        while ($row = $result->fetch_row()) {
            var_dump($row);
        }
        $result->free();
    }
} while ($conn->more_results() && $conn->next_result());

使用这段代码,您的测试用例可以像预期的那样,

代码语言:javascript
复制
array(1) {
  [0] =>
  string(4) "test"
}
票数 1
EN

Stack Overflow用户

发布于 2015-07-12 19:39:41

如果php5ts.dll或apache的任何其他部分在你每次运行短脚本时都会以可重现的方式崩溃,那么你很可能在php中遇到了错误。特别是如果你用从php.net下载的最新PHP版本运行最新的apache,你有很好的机会得到PHP团队的支持。因此,请通读https://bugs.php.net/how-to-report.php,看看在没有apache (在使用php.exe的cli上的单独脚本中)和generate a backtrace的情况下运行脚本时是否可以重现崩溃,然后您可以将其作为错误提交。

像这样的but有时是可以解决的,但很少能从脚本的上下文中修复。PHP永远不应该使can服务器崩溃,如果它重复这样做,则应该归档一个错误,以便可以修复它

票数 6
EN

Stack Overflow用户

发布于 2015-07-15 23:10:06

我发现了如何重现它,我相信这是一个php/apache bug

PHP代码:

代码语言:javascript
复制
if (!($stmt = $mysqli->prepare("CALL test()"))) {
    echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}

if (!$stmt->execute()) {
    echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}

do {
    if ($res = $stmt->get_result()) {
        printf("---\n");
        //var_dump(mysqli_fetch_all($res));
        var_dump($res->fetch_assoc());
        mysqli_free_result($res);
    } else {
        if ($stmt->errno) {
            echo "Store failed: (" . $stmt->errno . ") " . $stmt->error;
        }
    }
} while ($stmt->more_results() && $stmt->next_result());

存储过程代码:

代码语言:javascript
复制
CREATE DEFINER=`root`@`localhost` PROCEDURE `test`()
BEGIN
declare test_var varchar(100) default "ciao";
declare bNoMoreRows bool default false;
declare test_cursor cursor for
    select id from tmp_folder;
declare continue handler for not found set bNoMoreRows := true;

create temporary table tmp_folder select "test" as id;

open test_cursor;

fetch test_cursor into test_var;

close test_cursor;

select test_var;

drop temporary table if exists tmp_folder;

END

打开的错误: Apache:https://bz.apache.org/bugzilla/show_bug.cgi?id=58136

Php:https://bugs.php.net/bug.php?id=70073

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31279884

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档