Подтвердить что ты не робот

Ошибка Apache Apache при выполнении ЗАП. ПРОЦЕДУРЫ

Проблема

Когда я выполняю следующий код (я вызываю хранимую процедуру с параметрами 5 IN и 1 OUT)

$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 - Перезапуск.

Что я пробовал

  • Этот код работает нормально и корректно возвращает результаты:
$conn->query("SET @res = ''");
$res=$conn->query("CALL retrieve_matches(5,3, 16, 2, false, @res)");
var_dump($res->fetch_assoc());

ПРИМЕЧАНИЕ. Тот же код выше, что делает сбой Apache, работает корректно, если я просто изменяю номер во входе хранимой процедуры, например:

if (!($stmt = $mysqli->prepare("CALL retrieve_matches(5,6, 16, 2, false, @res)"))) {
  1. Исправлено из Workbench MySQl, и оба вызова работают нормально.
  2. Я использую WAMP 64b на WIN7 Enterprise 64b, я пробовал с WAMP 32b, но получил такую ​​же проблему.
  3. Я проверил событие Windows и обнаружил, что сбой httpd.exe вызван php5ts.dll
  4. Если вы ищете "httpd.exe php5ts.dll" в google, вы можете найти много людей, занимающихся этой проблемой. Но я не нашел решение для WAMP...
  5. Пробовал с AMPPS, точно такую ​​же проблему

Журнал ошибок PHP

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

[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" вызывает другую хранимую процедуру в функции измененного значения. Я отлаживал хранимую процедуру "retrieve_standalone", которая является причиной сбоя Apache. Эта процедура выполняет select/insert, я проверил, и вставка выполнена правильно. НО внутри "retrieve_standalone" я использую курсор странным образом:

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;

если я не открываю курсор

open tmp_cursor;

все работает нормально!! Поэтому, я думаю, я нашел проблему сейчас: как я могу ее решить?

4b9b3361

Ответ 1

По-видимому, есть немного байка, проходящего - то есть scaricabarile - между ребятами PHP и ребятами из MySQLi.

Что-то происходит, так это то, что MySQLi реагирует "ненадлежащим образом" и возвращает неожиданное значение (я бы поставил небольшую сумму на него как NULL) на PHP, который был должным образом выпущен. Это поведение задокументировано, а вердикт от PHPland: "Не ошибка [PHP]". На их стороне, ребята MySQLi утверждают, что это PHP, который неправильно проверяет возвращенный результат. И эти "неправильные" результаты в любом случае зависели от вашего запроса.

Итак, я выхожу на конечность и полагаю, что ваша проблема связана с "трудностями общения", поэтому проблема возникает: "Ваш запрос заставляет MySQLi сбросить/снова подключиться". Почему это так? По-видимому (некоторые) хранимые процедуры требуют mysqli_multi_query, чтобы правильно вести себя.

И mysqli_multi_query не совместим с mysqli_prepare.

Поэтому я предлагаю попробовать без подготовки запроса и запустить его с помощью mysqli_multi_query.

$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());

С помощью этого кода ваш тестовый пример получит меня, как и ожидалось,

array(1) {
  [0] =>
  string(4) "test"
}

Ответ 2

Если php5ts.dll или любая другая часть Apache падает с повторяющимся воспроизведением каждый раз, когда вы запускаете короткий script, скорее всего, вы попали в ошибку в php. Особенно, если вы запускаете обновленный apache с недавней php-версией, загруженной с php.net, у вас есть очень хорошие шансы получить поддержку от команды PHP. Итак, прочитайте https://bugs.php.net/how-to-report.php, посмотрите, можете ли вы воспроизвести сбой при запуске script без apache (в отдельном script на cli, используя php.exe) и создать обратную трассировку, которую вы затем можете отправить как ошибку.

Ошибки, подобные этим, иногда могут обрабатываться, но редко фиксируются из контекста вашего script. PHP никогда не должен разбивать веб-сервер, и если он делает это воспроизводимо, ошибка должна быть подана, поэтому ее можно исправить.

Ответ 3

Я узнаю, как воспроизвести его, я считаю, что ошибка php/apache

PHP-код:

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());

Код процедуры хранения:

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

Ответ 4

Я думаю, вы путаете $conn и $stmt. Вот что у меня есть. (Он собирает результат в $out.)

if ($conn->multi_query($call)) {
    $raa = array();
    do {
        /* store first result set */
        if ($result = $conn->use_result()) {
            while ($row = $result->fetch_row()) {
                $raa[] = $row;
                printf("+\n");
            }
            $result->close();
        }
        $out[] = $raa;
        /* print divider */
        if ($conn->more_results()) {
            printf("-----------------\n");
        }
    } while ($conn->next_result());
}
else
    echo "err";