在 PHP 中,与许多其他编程语言一样,=
运算符将右侧操作数的值分配给左侧操作数变量。即这样的命令执行后,符号左侧命名的变量=
将包含符号右侧表达式的值=
。
您的右手操作数是一个双引号字符串字面量,其中 PHP 用它们的值扩展(替换)变量;但是,结果(分配给左侧操作数)只是一个字符序列。
PHP 的echo
构造将其参数转换为字符串,按顺序连接它们并将结果发送到输出缓冲区。
在您的情况下,唯一的参数是另一个双引号字符串 literal "$requete"
,其中 PHP 再次使用它们的值扩展变量:这次文字的内容仅仅是 variable $requete
,因此引用它只会导致多余的解析开销;并且由于该变量被分配了前一个字符串文字,因此结果字符串(由 输出echo
)等于原始字符串文字。因此,您的两个陈述具有相同的效果:
echo "SELECT login, pass FROM membres WHERE login='$login' AND pass='$pass'";
PHP 没有被告知存在 RDBMS,这是您希望由该 RDBMS 评估的 SQL,或者您希望输出生成的结果集。
更糟糕的是,除非您绝对确定并且$login
不$pass
包含未转义'
的字符,否则为 SQL 解析该字符串可能会导致意外行为。 攻击者经常利用这种疏忽来执行SQL 注入攻击,这可能会危及您的整个数据库。避免这种情况的最安全方法是永远不要评估SQL 的变量,而是使用准备好的语句,将变量作为参数传递到其中。
我建议您研究PHP Data Objects,它使安全数据库访问变得非常容易:
$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);
不过,有几点需要注意:
您只是从与常量值匹配的数据库字段中进行选择,这是毫无意义的:从此类查询中可以获得的唯一信息是数据库中匹配记录的数量,但是在返回多余的数据时会浪费资源。
相反,您可以SELECT COUNT(*) FROM membres WHERE ...
在不浪费任何开销的情况下获取相同的信息;或者如果您只想发现是否有一条或多条匹配记录,SELECT EXISTS (SELECT * FROM membres WHERE ...)
效率会更高。
您似乎正在创建一个登录脚本,以安全的方式完成这项工作并非易事:如果您有兴趣了解更多信息,请阅读The Definitive Guide To Forms based Website Authentication 。那里有一些库和工具,您可以将它们放入您的项目中,以避免在重新发明轮子上浪费资源(以及其他人从艰难中学到的所有许多痛苦的错误)。