У меня есть хранимая процедура IsUserPresent как:
DELIMITER $$ CREATE PROCEDURE IsUserPresent( in userid varchar (150), out isPresent bit ) BEGIN SET isPresent=0; SELECT COUNT(*) INTO isPresent FROM users_table WHERE users_table.userid=userid; END$$
и я хочу вызвать его из PHP с помощью подготовленного оператора mysqli. Я делаю это после фрагмента кода, но это дает мне предупреждение.
$connect=&ConnectDB(); $stmt=$connect->prepare("CALL IsUserPresent(?,?)"); $stmt->bind_param('si',$uid,$userCount); $stmt->execute(); $toRet = $userCount!=0; Disconnect($connect); return $toRet;
Предупреждения следующие:
Premature end of data (mysqlnd_wireprotocol.c:1112) Warning: mysqli_stmt::execute(): RSET_HEADER packet 1 bytes shorter than expected Warning: mysqli_stmt::execute(): Error reading result set's header
Порядок работы хранимых процедур с подготовленными операторами несколько сложнее. В руководстве PHP указано, что вы должны использовать переменные сеанса (сеансы MySQL, а не PHP)
Параметр INOUT / OUT
Доступ к значениям параметров INOUT / OUT осуществляется с использованием переменных сеанса.
Таким образом, вы можете сделать это с помощью
$connect=&ConnectDB(); // bind the first parameter to the session variable @uid $stmt = $connect->prepare('SET @uid := ?'); $stmt->bind_param('s', $uid); $stmt->execute(); // bind the second parameter to the session variable @userCount $stmt = $connect->prepare('SET @userCount := ?'); $stmt->bind_param('i', $userCount); $stmt->execute(); // execute the stored Procedure $result = $connect->query('call IsUserPresent(@uid, @userCount)'); // getting the value of the OUT parameter $r = $connect->query('SELECT @userCount as userCount'); $row = $r->fetch_assoc(); $toRet = ($row['userCount'] != 0);
Примечание:
Я рекомендую переписать эту процедуру как функцию с одним параметром IN, который возвращает INT.
Должен быть комментарий, но из-за публикации форматирования кода в качестве ответа.
Не могу комментировать PHP-код, я не программист, но ваша процедура должна быть примерно такой:
DELIMITER $$ CREATE PROCEDURE IsUserPresent( in p_userId varchar (150), out p_isPresent bit ) BEGIN SELECT EXISTS (SELECT 1 FROM users_table WHERE user_table.userid = p_userId) INTO p_isPresent; END$$
Используйте exists()
, поскольку он останавливается, как только будет найдена запись. count()
продолжает искать записи, хотя это необязательно.
И вы назвали параметр таким же, как имя вашего столбца. Это запутывает MySQL, и его следует избегать любой ценой. Хорошей практикой является префикс параметров с p_
и переменными с v_
и / или некоторые признаки того, какой тип является переменной или параметром.
Для лучшей читаемости я также изменил имена параметров на верблюд.
О, и, наконец, всегда включайте сообщения об ошибках в вопросах.