使用$ stmt-> bind_param()无法通过引用传递常量变量?

时间:2011-05-25 19:53:02

标签: php mysqli constants

这是我的代码段:

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()无法将常量变量作为参数的原因。

谢谢!

3 个答案:

答案 0 :(得分:3)

很简单,这是因为你不能通过引用传递一个常量,并且这样做是没有意义的,因为它是不可变的。顺便说一下,常数不是变量;它就在名字中。

答案 1 :(得分:0)

以下内容可以通过引用传递:

  • 变量,即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

答案 2 :(得分:0)

Mysqli的bind_param定义如下:

bind_param ( string $types , mixed &$var1 [, mixed &$... ] )

说明

&表示变量是通过引用传递的,因为PHP中的常量(例如DEFAULT_USER_LIMIT)不能以这种方式引用,它们只能作为值传递,因为它们就是这样。

因此,如果您有一个强制通过引用传递的函数,首先必须将常量的值存储到变量并传递变量(就像您所做的那样......)

现代解决方案 - 只需use 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 ]]] )