mysqli :: prepare()vs mysqli_stmt :: prepare()

时间:2014-01-27 11:47:42

标签: php mysqli

我使用以下代码使用预准备语句进行查询: 我使用mysqli :: prepare(),而不是mysqli_stmt :: prepare(),所以$ res不必初始化。它由mysqli :: prepared返回。 php.net link

$sql2 = "INSERT INTO best_scores(`user_id`, `test_id`, `score`) VALUES(?, ?, ?)";
if($res = $db->prepare($sql2) == FALSE) echo $db->error . "\n";
$res->bind_param("sii", $user_id, $_GET['test'], $max);
$res->execute();
$res->free_result();

当达到该代码时,出现以下错误:

Call to a member function bind_param() on a non-object

我寻找答案,但所有问题都在SQL查询字符串中出错,或者他们没有释放以前的结果。他们都没有帮助我,所以我试图改变一些东西。我将代码更改为:

$sql2 = "INSERT INTO best_scores(`user_id`, `test_id`, `score`) VALUES(?, ?, ?)";
$res = $db->stmt_init();
if($res->prepare($sql2) == FALSE) echo $db->error . "\n";
$res->bind_param("sii", $user_id, $_GET['test'], $max);
$res->execute();
$res->free_result();

现在它正在运作。但为什么它有所不同?第一次尝试有什么问题?

编辑:我的$ db对象定义如下:

$db = new mysqli("localhost", "user", "pass", "database");
if($db->connect_errno > 0) {
    die('Unable to connect to database [' . $db->connect_error . ']');
}

3 个答案:

答案 0 :(得分:3)

正如我们在评论中讨论的那样,它可能是if()块中的错误分配。

我测试了什么。如果阻止,像你的那样:

$x = (object)array('a'=>'b');

if ($a = $x == false) {
    echo 'a';
}

var_dump($a);

输出:

  

布尔值假

然后我在括号中加上了括号:

$x = (object)array('a'=>'b');


if (($a = $x) == false) {
    echo 'a';
}

var_dump($a);

输出:

  

object(stdClass)[1] public'a'=>字符串'b'(长度= 1)

因此您需要在$ res

的分配周围添加括号
if(($res = $db->prepare($sql2)) == FALSE) 

因为你的方式,你错误地将$ res重新分配给FALSE并且对象已经丢失

答案 1 :(得分:1)

您正在检查您的db-> prepare是否在第一个示例中工作,如果不是,您仍然使用$ res,现在不是对象,因为它未初始化。 在第二个示例中,您首先声明并初始化它。

答案 2 :(得分:1)

在文档中:

mysqli_stmt_init - 初始化一个语句并返回一个与mysqli_stmt_prepare一起使用的对象

在你的prev代码中你没有初始化。在初始化后的第二个代码片段中工作。

链接:http://www.php.net/manual/en/mysqli.stmt-init.php