Can't pass a constant variable by reference with $stmt->bind_param()?
This is my code snippet:
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
is defined as 8
, but with the above code I get this error:
Fatal error: Cannot pass p开发者_运维问答arameter 3 by reference in C:\xampp\htdocs\classes\limits.class.php on line 38
But if I do this:
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;
}
It works. I was just wondering why this happens, as it doesn't really make sense to me. I don't see any reason why bind_param()
can't take a constant variable as a parameter.
Thanks!
Quite simply, it's because you can't pass a constant by reference, and there would be no point in doing so, as it is immutable. Constants, by the way, are not variables; it's right there in the name.
Mysqli's bind_param is defined like this:
bind_param ( string $types , mixed &$var1 [, mixed &$... ] )
Explanation
&
means that variable is passed by reference and because constants (e.g.DEFAULT_USER_LIMIT
) in PHP can not be referenced this way, they can only be passed as values because that's what they are.
So if you have a function that enforces passing by reference, first you must store the value of the constant to a variable and pass the variable (as you did...)
Modern solution - just use PDO
If you can use PDO interface and don't need to pass values by reference,
just use PDO's bindValue()
+ PDO in common cases is used almost the same way as Mysqli.
public bool PDOStatement::bindValue ( mixed $parameter , mixed $value [, int $data_type = PDO::PARAM_STR ] )
And if you'd still need to pass by reference, PDO also has a bindParam()
public bool PDOStatement::bindParam ( mixed $parameter , mixed &$variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )
The following things can be passed by reference:
- Variables, i.e. foo($a)
- New statements, i.e. foo(new foobar())
- References returned from function
No other expressions should be passed by reference, as the result is undefined
http://php.net/manual/en/language.references.pass.php
additionally,
mysqli_stmt_bind_param() requires parameters to be passed by reference, whereas call_user_func_array() can accept as a parameter a list of variables that can represent references or values.
http://php.net/manual/en/mysqli-stmt.bind-param.php
精彩评论