这是我的代码片段:
private function add_user_limit()
{
global $mysqli;
$stmt = $mysqli->prepare("INSERT INTO `user_limits` (user_ip, downloads_left) VALUES (?, ?)");
$stmt->bind_param("si", $this->user_ip, DEFAULT_USER_LIMIT);
$stmt->execute();
if($stmt->affected_rows == 0)
throw new Exception("Couldn't add new user to the user_limits table");
$stmt->close();
$this->downloads_left = DEFAULT_USER_LIMIT;
}
DEFAULT_USER_LIMIT
被定义为8
,但使用上面的代码,我得到了这个错误:
Fatal error: Cannot pass parameter 3 by reference in C:'xampp'htdocs'classes'limits.class.php on line 38
但如果我这样做:
private function add_user_limit()
{
global $mysqli;
$stmt = $mysqli->prepare("INSERT INTO `user_limits` (user_ip, downloads_left) VALUES (?, ?)");
$user_limit = DEFAULT_USER_LIMIT; // For some reason we can't pass a constant to bind_param
$stmt->bind_param("si", $this->user_ip, $user_limit);
$stmt->execute();
if($stmt->affected_rows == 0)
throw new Exception("Couldn't add new user to the user_limits table");
$stmt->close();
$this->downloads_left = DEFAULT_USER_LIMIT;
}
它有效。我只是想知道为什么会发生这种情况,因为这对我来说真的没有意义。我看不出bind_param()
为什么不能将常量变量作为参数。
谢谢!
很简单,这是因为不能通过引用传递常量,这样做没有意义,因为它是不可变的。顺便说一句,常数不是变量;它就在名字里。
bind_param ( string $types , mixed &$var1 [, mixed &$... ] )
解释
&
意味着变量是通过引用传递的,因为PHP中的常量(例如DEFAULT_USER_LIMIT
)不能通过这种方式引用,所以它们只能作为值传递,因为它们就是这样。
因此,如果你有一个函数强制通过引用传递,首先你必须将常量的值存储到一个变量中,并传递变量(就像你所做的那样…)
现代解决方案-只需使用PDO
如果您可以使用PDO接口,并且不需要通过引用传递值,
只使用PDO的bindValue()
+PDO在常见情况下的使用方式与Mysqli几乎相同。
public bool PDOStatement::bindValue ( mixed $parameter , mixed $value [, int $data_type = PDO::PARAM_STR ] )
如果你仍然需要通过引用,PDO也有一个bindParam()
public bool PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )
以下内容可以通过引用传递:
- 变量,即foo($a)
- 新语句,即foo(New foobar())
- 从函数返回的引用
不应通过引用传递其他表达式,因为结果是未定义的
http://php.net/manual/en/language.references.pass.php
此外,
mysqli_stmt_bind_param()要求参数由引用传递,而call_user_func_array()可以接受表示引用或值的变量列表作为参数。
http://php.net/manual/en/mysqli-stmt.bind-param.php