我正在使用 MySQLi 编写 PHP 应用程序。在这个应用程序的运行过程中,我连续准备了许多 SQL 准备好的语句,然后在整个应用程序的过程中根据需要执行它们。
但是,当我在应用程序中运行相同的特定语句两次(使用特定参数)时,我收到以下错误:
mysqli_stmt::execute(): Premature EOF in result field metadata
。
为了进一步澄清我的问题,我附上了我的代码的最小可重现示例。首先,我的数据库包含一个名为
GET_USER_ID_FROM_USERNAME
的存储过程。这正是顾名思义 - 它接受一个字符串用户名作为参数,检查用户名是否存在,然后返回两个值 - 一个标记为 User_Exists
的布尔值,用于检查数据库中是否已知用户名,以及(如果前者)是 true
)一个标记为 ID
的整数。这是此过程的代码:
CREATE PROCEDURE GET_USER_ID_FROM_USERNAME (IN Username_Param TINYTEXT CHARSET utf8mb4)
BEGIN
IF ((SELECT COUNT(1) FROM Users WHERE Username = Username_Param) = 1) THEN
SELECT ID, TRUE AS User_Exists FROM Users WHERE Username = Username_Param;
ELSE
SELECT FALSE AS User_Exists;
END IF;
END
这完全按照我想要的方式工作 - 当我传入已知用户名时,它会在
true
列中返回 User_Exists
并在同名列中返回相关用户的 ID
,当我传入不具有特征的用户名时在数据库中,它在 false
列中返回 User_Exists
。
当我调用此过程两次(即使我在中间调用其他过程)时,就会出现问题,并且仅当第一次是现有用户名而第二次是未知用户名时(即当User_Exists
时)第一次的值为
true
,第二次为
false
)。我使用准备好的语句调用此例程,并将所需的用户名绑定到该语句。这是抛出所需错误的代码的最小示例:
// CONNECT
$mysqli = new mysqli("localhost", "root", "root", "test_database");
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli->autocommit(false);
$mysqli->set_charset('utf8mb4');
// PREPARE STATEMENT
$stmt = $mysqli->prepare("CALL GET_USER_ID_FROM_USERNAME (?);");
// BIND PARAMETER
$username = "";
$stmt->bind_param("s", $username);
// EXECUTE WITH KNOWN VALUE
$username = "Existing_Username";
$stmt->execute();
// Flush result (if I exclude this I get a "commands out of sync" error)
$stmt->get_result();
$mysqli->next_result();
// All fine so far
// EXECUTE WITH UNKNOWN VALUE
$username = "Fake_Username";
$stmt->execute(); // <- Error thrown here: mysqli_stmt::execute(): Premature EOF in result field metadata
此(且仅此)配置(其中第一个用户名已知而第二个用户名未知)会引发错误。如果该语句仅使用已知或未知的用户名调用一次,它将返回我所期望的结果。如果首先使用已知用户名调用该语句,然后使用不同的已知用户名调用该语句,它也会返回我所期望的结果。寻找错误信息
Premature EOF in result field metadata
没有结果。如果有人知道此消息如何或为何出现,或者知道我的代码做错了什么,我将不胜感激!这是我为了本示例的目的而设置的
Users
表:
CREATE TABLE Users (
ID BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
Username TINYTEXT NOT NULL,
Pass_Hash TINYTEXT NOT NULL
);
行:
ID - Username - Pass_Hash
------------------------------------------------------------------------------------------
1 Existing_Username $2y$10$l8y.GEK3LFnLyJWhAmHdg.7lMb45SezorBDODrqWUq4M0K1P3rDCq
(Pass_Hash 是 Password1
,经过哈希处理)。我正在运行的设置:
Windows 上的 MAMP
PHP 8.1.0
MySQL 5.7.24