【问题标题】:What is the meaning of "Only variables should be passed by reference" in PHP?PHP中“只有变量应该通过引用传递”是什么意思?
【发布时间】:2018-02-06 22:52:52
【问题描述】:

代码:

public function login($email , $password){
    $stmt =$this->pdo->prepare("SELECT 'user_id' FROM 'users' WHERE 'email' = :email AND 'password' =: password");
     $stmt->bindParam(":email", $email, PDO::PARAM_STR);
     $stmt->bindParam(":password", md5($password), PDO::PARAM_STR);
     $stmt->execute();

     $users = $stmt->fetch(PDO::FETCH_OBJ);
     $count = $stmt->rowCount();

     if($count > 0) {
        $_SESSION['user_id'] = $user->user_id;
        header('Location : home.php');
        }else {
           return false;

        }
  }
}

错误:

注意:在第 18 行的 C:\xampp8\htdocs\social\core\classes\user.php 中,只能通过引用传递变量

警告:PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match the number of tokens in C:\xampp8\htdocs\social\core\classes\user.php 上线19

【问题讨论】:

  • 您的代码在太多级别上失败了。
  • 不要使用md5() 进行密码散列。 这是非常不安全的。请改用 PHP 的 password_hash()password_verify()。如果您运行的 PHP 版本低于 5.5(我真的希望您不是),您可以使用 password_compat library 来获得相同的功能。
  • 我几乎不敢为此提交答案。
  • @FunkFortyNiner - 在我意识到这是一个比最初看起来更深的兔子洞之前,我开始写一条新评论并做出一些解释。
  • @MagnusEriksson 我会碰碰运气的。

标签: php database pdo


【解决方案1】:

如果那是您的实际代码,您的命名占位符 =: password 和标题 Location : home.php 中有空格,它们计算并在列名周围使用单引号(错误的 identifier qualifiers)而不是刻度,但它们' 无论如何都不需要,因为没有 SQL 会抱怨的列名。

注意:$user->user_id; - $user 没有引用且未定义,您希望在此处使用$users。您的代码末尾还有一个额外的关闭 } 大括号,并且不确定您上面是否还有其他内容。如果没有,请将其删除。

请参阅有关密码参考的“编辑”。

public function login($email , $password){
    $stmt =$this->pdo->prepare("SELECT user_id FROM users 
                                WHERE email = :email AND password =:password");
     $stmt->bindParam(":email", $email, PDO::PARAM_STR);
     $stmt->bindParam(":password", $password, PDO::PARAM_STR);
     $stmt->execute();

     $users = $stmt->fetch(PDO::FETCH_OBJ);
     $count = $stmt->rowCount();

     if($count > 0) {
        $_SESSION['user_id'] = $users->user_id;
        header('Location: home.php');
        exit; // added to prevent further execution
        }else {
           return false;

        }
  }
} // << that brace should probably not be there.

正如Magnus 在 cmets 中所述,不要使用 MD5。使用password_hash(),因为那个旧方法陈旧且不安全。当您使用更安全的方法时,请确保密码长度足以容纳散列。

还要确保会话数组具有值。如果没有,那么很可能您没有使用 session_start(); 开始会话。

编辑:

如下面的 cmets 所述,将变量分配给 md5($password),而不是将其作为引用传递。

$password = md5($password); // wherever this is coming from.

然后

$stmt->bindParam(":password", $password, PDO::PARAM_STR); // in the code above

如果您还没有这样做,请使用适当的错误处理。

【讨论】:

  • 不要忘记$user-&gt;user_id 将失败,因为结果存储在名为$users 的变量中。
  • 关于“只有变量应该通过引用传递”的通知仍然存在:$stmt-&gt;bindParam(":password", md5($password),...
  • @MagnusEriksson 对;那应该是$users-&gt;user_id; 有一个多元化?我想我已经在这里陷入了一个兔子洞哈哈!
  • 我不会将哈希分配给变量,而是使用bindValuePDO::PARAM_STR 也是多余的,因为无论如何您都在为语句提供字符串,因此不需要将它们转换为字符串。只是我的 0.02 美元。
  • @halfer 谢谢,我们会看看结果如何。如果我必须从潜在的兔子洞中找到出路,我只会放弃答案lol!
猜你喜欢
  • 2017-04-03
  • 1970-01-01
  • 1970-01-01
  • 2021-07-11
  • 2011-10-16
相关资源
最近更新 更多