这是我的PHP:
$db = new mysqli($db_host, $db_user, $db_pass, $db_database);
if (mysqli_connect_errno()) {
echo "Could not connect to database.";
}
// On first connect to database, create a user to hold data for users not logged in
$stmt = $db->prepare("SELECT id FROM users WHERE id = ?");
$stmt->bind_param("i" , 1);
$stmt->execute();
if ($stmt->num_rows == 0) {
$stmt = $db->prepare("INSERT INTO users (id, username, email, password) VALUES (?, ?, ?, ?");
$stmt->bind_param("isss", 1, "anonymous", "anonymous", password_hash("noidentity", PASSWORD_BCRYPT));
$stmt->execute();
}
但是当它运行时,我收到了这个错误:
致命错误:无法通过引用传递参数2
它指向我有$stmt->bind_param("i" , 1);
我不确定我做错了什么。
另外,如果我想将行中某个字段的值设置为高于当前值的1,那么如何使用预准备语句执行此操作?
这个,例如:UPDATE users SET wins = wins + 1 WHERE id = ?
设置胜出是一个值,所以我认为它应该与预备语句一起使用,但我认为“wins + 1”是一个字符串,并包括在准备好的声明中?
答案 0 :(得分:4)
bind_param
的所有参数(第一个除外)都必须是通过引用传递的变量,您不能只传递1
,"anonymous"
等文字值...
如果要插入的值是这样固定的,那么使用bind_param
毫无意义,因为在查询中使用它们是完全安全的:
$stmt = $bd->prepare("INSERT INTO users (id, username, email, password) VALUES (1, 'anonymous',...)");
但是一般来说,您需要将这些参数放入变量中,例如:
$params = Array(1,"anonymous","anonymous",password_hash("noidentity",PASSWORD_BCRYPT));
$stmt->bind_param("isss",$params[0],$params[1],$params[2],$params[3]);
答案 1 :(得分:0)
$param = 1;
$stmt->bind_param("i" , $param);
因为您无法在绑定中传递值,只能传递参数。
答案 2 :(得分:0)
这就是为什么我更喜欢PDO而不是Mysqli。
在PDO中,您不需要绑定任何内容,只需将值传递给execute()
,然后您可以按值传递它们,这样您就可以使用文字和表达式。
$stmt = $pdo->prepare("INSERT INTO users (id, username, email, password)
VALUES (?, ?, ?, ?");
$status = $stmt->execute(array(1, "anonymous", "anonymous",
password_hash("noidentity", PASSWORD_BCRYPT));
当然,在每次prepare()和execute()之后检查是否成功。
答案 3 :(得分:-1)
这段代码在逻辑上存在缺陷:
if (mysqli_connect_errno()) {
echo "Could not connect to database.";
}
如果不是错误,此函数将返回0
又名false
,更不用说这不会导致脚本退出或以其他方式跳过查询执行。您应该将其更改为:
$db = new mysqli($db_host, $db_user, $db_pass, $db_database)
if( $db->connect_error ) {
echo "Could not connect to database.\n" .
"Err: " . $db->connect_errno() . "\n" . $db->connect_error();
// die/exit/return error/throw exception, or...
} else {
// query prep/execution here
}
你也在混合面向对象和程序性调用,我不知道这是重要的还是不执行的,但它让人感到困惑。