Ошибки PHP из-за ошибки синхронизации

Я использую два подготовленных оператора в PHP / MySQLi для извлечения данных из базы данных mysql. Однако, когда я запускаю инструкции, я получаю сообщение «Команды не синхронизированы, вы не можете запустить команду сейчас».

Вот мой код:

$stmt = $mysqli->prepare("SELECT id, username, password, firstname, lastname, salt FROM members WHERE email = ? LIMIT 1"; $stmt->bind_param('s', $loweredEmail); $stmt->execute(); $stmt->store_result(); $stmt->bind_result($user_id, $username, $db_password, $firstname, $lastname, $salt); $stmt->fetch(); $stmt->free_result(); $stmt->close(); while($mysqli->more_results()){ $mysqli->next_result(); } $stmt1 = $mysqli->prepare("SELECT privileges FROM delegations WHERE id = ? LIMIT 1"); //This is where the error is generated $stmt1->bind_param('s', $user_id); $stmt1->execute(); $stmt1->store_result(); $stmt1->bind_result($privileges); $stmt1->fetch(); 

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

  • Перемещение подготовленных операторов на два отдельных объекта.
  • Используя код:

     while($mysqli->more_results()){ $mysqli->next_result(); } //To make sure that no stray result data is left in buffer between the first //and second statements в while($mysqli->more_results()){ $mysqli->next_result(); } //To make sure that no stray result data is left in buffer between the first //and second statements 
  • Использование free_result () и mysqli_stmt-> close ()

PS: Ошибка «Out of Sync» исходит из «$ stmt1-> ошибки второго оператора»

В mysqli :: query Если вы используете MYSQLI_USE_RESULT, все последующие вызовы возвращают ошибки Команды не синхронизируются, если вы не вызываете mysqli_free_result ()

При вызове нескольких хранимых процедур вы можете выполнить следующую ошибку: «Команды не синхронизированы, вы не можете запустить эту команду сейчас». Это может произойти даже при использовании функции close () в объекте результата между вызовами. Чтобы устранить проблему, не забудьте вызвать функцию next_result () объекта mysqli после каждого вызова хранимой процедуры. См. Пример ниже:

 <?php // New Connection $db = new mysqli('localhost','user','pass','database'); // Check for errors if(mysqli_connect_errno()){ echo mysqli_connect_error(); } // 1st Query $result = $db->query("call getUsers()"); if($result){ // Cycle through results while ($row = $result->fetch_object()){ $user_arr[] = $row; } // Free result set $result->close(); $db->next_result(); } // 2nd Query $result = $db->query("call getGroups()"); if($result){ // Cycle through results while ($row = $result->fetch_object()){ $group_arr[] = $row; } // Free result set $result->close(); $db->next_result(); } else echo($db->error); // Close connection $db->close(); ?> 

Я надеюсь, это поможет

«Команды не синхронизированы, вы не можете запустить эту команду сейчас»

Подробности об этой ошибке можно найти в документах mysql. Чтение этих деталей дает понять, что результирующие наборы готового исполнения выполнения должны быть полностью загружены до выполнения другого подготовленного оператора в том же соединении.

Устранение проблемы может быть выполнено с помощью вызова результата хранилища. Вот пример того, что я изначально пытался сделать:

 <?php $db_connection = new mysqli('127.0.0.1', 'user', '', 'test'); $post_stmt = $db_connection->prepare("select id, title from post where id = 1000"); $comment_stmt = $db_connection->prepare("select user_id from comment where post_id = ?"); if ($post_stmt->execute()) { $post_stmt->bind_result($post_id, $post_title); if ($post_stmt->fetch()) { $comments = array(); $comment_stmt->bind_param('i', $post_id); if ($comment_stmt->execute()) { $comment_stmt->bind_result($user_id); while ($comment_stmt->fetch()) { array_push($comments, array('user_id' => $user_id)); } } else { printf("Comment statement error: %s\n", $comment_stmt->error); } } } else { printf("Post statement error: %s\n", $post_stmt->error); } $post_stmt->close(); $comment_stmt->close(); $db_connection->close(); printf("ID: %d -> %s\n", $post_id, $post_title); print_r($comments); ?> 

Приведенное выше приведет к следующей ошибке:

Ошибка описания комментариев: команды не синхронизированы; вы не можете запустить эту команду сейчас

PHP Примечание: неопределенная переменная: post_title в error.php в строке 41 ID: 9033 -> Array ()

Вот что нужно сделать для правильной работы:

 <?php $db_connection = new mysqli('127.0.0.1', 'user', '', 'test'); $post_stmt = $db_connection->prepare("select id, title from post where id = 1000"); $comment_stmt = $db_connection->prepare("select user_id from comment where post_id = ?"); if ($post_stmt->execute()) { $post_stmt->store_result(); $post_stmt->bind_result($post_id, $post_title); if ($post_stmt->fetch()) { $comments = array(); $comment_stmt->bind_param('i', $post_id); if ($comment_stmt->execute()) { $comment_stmt->bind_result($user_id); while ($comment_stmt->fetch()) { array_push($comments, array('user_id' => $user_id)); } } else { printf("Comment statement error: %s\n", $comment_stmt->error); } } $post_stmt->free_result(); } else { printf("Post statement error: %s\n", $post_stmt->error); } $post_stmt->close(); $comment_stmt->close(); $db_connection->close(); printf("ID: %d -> %s\n", $post_id, $post_title); print_r($comments); ?> 

Несколько вещей, чтобы отметить пример выше:

 The bind and fetch on the statement still works correctly. Make sure the results are freed when the processing is done. 

Для тех из вас, кто делает правильные вещи и использует хранимые процедуры с подготовленными заявлениями.

По какой-то причине mysqli не может освобождать ресурсы при использовании выходной переменной в качестве параметра хранимой процедуры. Чтобы исправить это, просто верните набор записей внутри тела процедуры вместо сохранения значения в выходной переменной / параметре.

Например, вместо SET outputVar = LAST_INSERT_ID (); вы можете иметь SELECT LAST_INSERT_ID (); Затем в PHP я получаю возвращаемое значение следующим образом:

 $query= "CALL mysp_Insert_SomeData(?,?)"; $stmt = $mysqli->prepare($query); $stmt->bind_param("is", $input_param_1, $input_param_2); $stmt->execute() or trigger_error($mysqli->error); // trigger_error here is just for troubleshooting, remove when productionizing the code $stmt->store_result(); $stmt->bind_result($output_value); $stmt->fetch(); $stmt->free_result(); $stmt->close(); $mysqli->next_result(); echo $output_value; 

Теперь вы готовы выполнить вторую хранимую процедуру, не выполнив ошибку «Команды не синхронизируются, вы не можете запустить команду сейчас». Если вы возвращаете более одного значения в наборе записей, вы можете выполнить цикл и получить все из них следующим образом:

 while ($stmt->fetch()) { echo $output_value; } 

Если вы возвращаете более одного набора записей из хранимой процедуры (у вас есть несколько выборок), убедитесь, что вы прошли через все эти записи с помощью $ stmt-> next_result ();