【问题标题】:PHP - Prepared Statement Query doesn't work the second timePHP - 准备好的语句查询第二次不起作用
【发布时间】:2017-01-31 18:10:37
【问题描述】:

所以,我正在使用 PHP 并将准备好的语句发送到 MySQL 数据库。我遇到了一个我无法调试的问题。这是我的代码:

        // Check if the input username is in the database
		$stmtQuery = "SELECT * FROM updatedplayers WHERE Player=?;";
		$preparedStmt = $dbc->prepare($stmtQuery);
		$preparedStmt->bind_param("s", $setUsername);

		$preparedStmt->execute();
		$preparedStmt->bind_result($resultUUID, $resultUsername);
		$preparedStmt->fetch();

		// If it's not, kill the page.
		if ($resultUUID == null) {

			incorrect();
		}
		
		$stmtQuery = "SELECT Password, Salt FROM logins WHERE UUID=?;";
		echo 'flag1 ';
		$preparedStmt = $dbc->prepare($stmtQuery);
		echo 'flag2 ';
		$preparedStmt->bind_param("s", $resultUUID);
		echo 'flag3 ';

第一个准备好的语句工作正常,它位于$preparedStmt->bind_param("s", $resultUUID); 行。在这些之前还有一些其他准备好的语句,所以我知道我这样做是正确的,但我不太确定最后一个语句。

代码似乎在echo 'flag2 '; 之后停止运行,我把它放在那里是为了找到特定的行。我没有收到任何错误消息,只是没有打印出flag3
我试过用静态字符串替换$resultUUID,但我得到了相同的结果。另外,我知道我的 SQL 语句格式正确,我已经在控制台中手动进行了测试。

差不多就是这样,我很想听到一些批评,因为我是 PHP 新手。此外,有什么方法可以更好地了解我得到的错误,而不是自己尝试查明错误?谢谢!

【问题讨论】:

标签: php mysql prepared-statement


【解决方案1】:

所以,添加 @user2182349 建议的 ini_set('display_error', 1); 让我有了更多的了解,我得到了“致命错误:在布尔值上调用成员函数 bind_param()”

some research 之后,我尝试添加mysqli_report(MYSQLI_REPORT_ALL);,结果抛出“No index used in query/prepared statement”

我对此进行了some research 以意识到这不是问题,只是 MySQLI 报告了不必要的错误(这我要求它做的,哈哈)。为了获得更好、更深入的堆栈跟踪,我使用了mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

这导致“命令不同步;您现在无法运行此命令”。同样,more research 教我使用 $preparedStmt->store_result();,以便运行另一个准备好的语句。

非常感谢大家的帮助,希望这也可以帮助某人。

【讨论】:

    【解决方案2】:

    您应该能够使用类似于此的单个 select 语句:

    SELECT u.UUID, u.Username, l.Password, l.Salt 
        FROM updatedplayers AS u 
        JOIN logins AS l ON (u.UUID = l.UUID) 
        WHERE u.Player = ?
    

    检查字段名称的大小写以确保它们与数据库匹配。

    在文件顶部,添加 ini_set('display_errors',1);。如果您有任何 PHP 错误,它们将被显示出来。还要检查数据库调用的返回值并使用错误显示函数。

    【讨论】:

    • 谢谢,有机会我会试试这个的,我会尽快回复你的。
    【解决方案3】:

    我认为您需要在将变量用于另一个查询之前关闭准备好的语句:

    $preparedStmt->close();
    

    或者为第二个查询使用另一个变量名,例如 $preparedStmt2

    【讨论】:

    • 我知道情况并非如此,因为我已经做了多个准备好的语句,而不必在每个语句之后关闭它。 ://
    • 按照手册,php.net/manual/en/mysqli.quickstart.prepared-statements.php,参见示例#3 executed multiple times,没有关闭。
    • @chris85..INSERT is different FROM SELECT ...我对 INSERT 多次没有问题..但我在选择多次时遇到了麻烦..这就是我转向使用 PDO 的原因..
    • @victor 查看正在使用的函数。这是相同的数据库交互。
    • @chris85 .. 是的,但它是不同的表......当我使用 MySQLi 时,我遇到了这个问题......并且一直在寻找答案但没有运气......所以我不得不重新做我的图书馆使用 PDO .. PDO 是 SWEET .. 我使用 PDO 已经 4 年了...
    【解决方案4】:

    我建议你应该开始使用 PDO... 我在几年前遇到了 mysqli 准备语句的问题。从那时起,当涉及到多个查询时,PDO 让我不再头疼。

    您应该尝试 PDO.. :-) 它更有效。

    http://php.net/manual/en/intro.pdo.php http://php.net/manual/en/class.pdostatement.php

    或者您可以执行以下“如果您想要替代解决方案”..

    //Close connection
    $preparedStmt->close();
    
    //AND OPEN YOUR CONNECTION AGAIN TO PREPARE NEW QUERIES..
    
    $stmtQuery = "SELECT Password, Salt FROM logins WHERE UUID=?;";
    echo 'flag1 ';
    $preparedStmt = $dbc->prepare($stmtQuery);
    echo 'flag2 ';
    $preparedStmt->bind_param("s", $resultUUID);
    echo 'flag3 ';
    

    【讨论】:

    • 这并不能回答问题,它是一种可能有效也可能无效的替代方法。
    • 我在这里编辑了我的答案...对于“替代解决方案”
    • 但对我来说..答案是使用 PDO...我之前已经修补过“替代解决方案”但效果不佳...
    猜你喜欢
    • 1970-01-01
    • 2015-10-11
    • 2017-03-15
    • 2012-06-07
    • 2011-11-10
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多