如何在PHP中将变量传递给MySQL查询?

use*_*987 0 php mysql

我有以下MySQL命令试图获取用户的登录信息:

$requete = "SELECT login, pass FROM membres WHERE login='$login' AND pass='$pass'";
echo ("$requete");
Run Code Online (Sandbox Code Playgroud)

它不起作用.问题是,在执行此代码时,我看到以下输出(而不是执行查询的结果):

SELECT login, pass FROM membres WHERE login='$login' AND pass='$pass'
Run Code Online (Sandbox Code Playgroud)

在PHP中将变量传递给MySQL查询的正确方法是什么?

egg*_*yal 10

在PHP中,与许多其他编程语言一样,=运算符右侧操作数的值分配给左侧操作数变量.也就是说,在执行这样的命令之后,=符号左侧的变量将包含符号右侧的表达式的值=.

你的右手操作数是一个双引号字符串文字,其中PHP用它们的值扩展(替换)变量; 但是,结果(分配给左侧操作数)仅仅是一系列字符.

PHP的echo构造将其参数转换为字符串(s),按顺序连接它们并将结果发送到输出缓冲区.

在你的情况下,唯一的参数是另一个双引号字符串文字"$requete",其中PHP再次使用它们的值扩展变量:这次文字的内容只是变量$requete,因此引用它只会导致多余的解析开销; 并且由于该变量被赋予了前一个字符串文字,因此生成的字符串(即输出echo)等于原始字符串文字.因此,您的两个陈述具有与以下相同的效果:

echo "SELECT login, pass FROM membres WHERE login='$login' AND pass='$pass'";
Run Code Online (Sandbox Code Playgroud)

PHP尚未被告知存在RDBMS,这是您希望由该RDBMS评估的SQL,或者您希望输出生成的结果集的SQL.

更糟的是,除非你是绝对肯定的是$login$pass不包含转义'字符,解析该字符串SQL可能会导致意外的行为. 攻击者经常利用这种疏忽来执行SQL注入攻击,这可能会危害整个数据库.在最安全的避免这种情况的方法是永远不会被替代使用,以评估SQL变量,准备的语句在其中传递您的变量作为参数.

我建议你研究PHP数据对象,这使得安全的数据库访问非常容易:

$dbh = new PDO("mysql:dbname=$dbname;charset=utf8", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$qry = $dbh->prepare('
  SELECT login, pass
  FROM   membres
  WHERE  login = ? AND pass = ?
');

$qry->execute(array($login, $pass));
while ($row = $qry->fetch(PDO::FETCH_ASSOC)) print_r($row);
Run Code Online (Sandbox Code Playgroud)

但是,有些事情需要注意:

  1. 您只是从与常量值匹配的数据库字段中进行选择,这是毫无意义的:从这样的查询中可以获得的唯一信息是数据库中匹配记录的数量,但是在返回多余数据时会浪费资源.

    相反,您可以SELECT COUNT(*) FROM membres WHERE ...在不浪费任何开销的情况下获取相同的信息; 或者如果您只想发现是否有一个或多个匹配的记录,SELECT EXISTS (SELECT * FROM membres WHERE ...)那么效率会更高.

  2. 您似乎正在创建一个登录脚本,这是以安全的方式完成的非常重要的事情:如果您有兴趣了解更多信息,请阅读基于表单的网站身份验证的权威指南.有图书馆和工具,你可以插入你的项目,以避免浪费资源重新发明轮子(以及其他许多痛苦的错误,其他人学到了很多困难).

  • 为此+1,但我认为他现在不能理解这一点 (3认同)