bind_param完成什么?

问题描述 投票:12回答:2

我正在学习避免SQL注入,但有点困惑。

使用bind_param时,我不明白目的。在手册页上,我找到了以下示例:

$stmt = mysqli_prepare($link, "INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt, 'sssd', $code, $language, $official, $percent);

$code = 'DEU';
$language = 'Bavarian';
$official = "F";
$percent = 11.2;

现在,假设这四个变量是用户输入的,我不明白这如何防止SQL注入。据我了解,他们仍然可以在其中输入任何内容。

我也找不到其中的'sssd'解释。它有什么作用?那是什么使它更安全?

[最后一个问题:我读到另一个问题,mysqli_real_escape_string已过时,但在手册中并未说明。如何弃用?由于某种原因,它不能再转义特殊字符吗?

注意:这个问题解释了bind_param的作用,但是我仍然不明白为什么它更安全或更受保护。Bind_param explanation

php sql mysqli sql-injection bindparam
2个回答
15
投票

现在,假设这四个变量是用户输入的,我不明白如何防止SQL注入。据我了解,他们仍然可以在其中输入他们想要的任何内容。

主要原理是使用准备好的语句,该语句用于向数据库服务器发送安全查询,这可以通过转义不属于实际查询的用户输入,并且也可以不使用任何查询(where子句)来检查查询来完成。在使用任何参数之前,请检查查询的有效性。

从这个问题出发:PDO sends raw query to MySQL while Mysqli sends prepared query, both produce the same result

$stmt = $mysqli->prepare("SELECT * FROM users WHERE username =?")) {
$stmt->bind_param("i", $user);
$user = "''1''";

服务器日志:

  130802 23:39:39   175 Connect   ****@localhost on testdb
    175 Prepare   SELECT * FROM users WHERE username =?
    175 Execute   SELECT * FROM users WHERE username =0
    175 Quit

通过使用准备好的语句,数据库服务器将检查不带任何参数的查询,在此阶段,在绑定任何参数之前可以检测到错误,然后,如果查询有效,则参数也将被发送到服务器以完成查询。

摘自PHP手册http://php.net/manual/en/mysqli.quickstart.prepared-statements.php

转义和SQL注入

绑定变量将由服务器自动转义。的服务器将其转义值插入适当的位置执行之前的语句模板。必须提供一个提示给服务器为绑定变量的类型,创建一个合适的转换。有关更多信息,请参见mysqli_stmt_bind_param()函数。信息。

..

我也无法在其中找到有关'sssd'的解释。是什么做?那是什么使它更安全?

答案在这里:http://php.net/manual/en/mysqli-stmt.bind-param.php

i
corresponding variable has type integer

d
corresponding variable has type double

s
corresponding variable has type string

b
corresponding variable is a blob and will be sent in packets

最后一个问题:我读了另一个问题,mysqli_real_escape_string已被弃用,但并未在手册。如何弃用?不能逃脱特殊字符出于某种原因了吗?

您能提供参考吗?我认为您对(mysql_real_escape_string()

有误解

11
投票

通过使用准备好的语句,您将SQL查询与用户输入的数据分开。您可以在SQL查询中放置占位符('?'char)而不是输入数据。然后,通过“ mysqli :: prepare”方法将查询发送到DBMS服务器(例如:MySQL)。因此,服务器检查一切正常,如果可以,则等待输入数据。到目前为止,它已经知道您的查询。只是它必须等待输入数据绑定到查询。

此时,“ bind_param”生效,将占位符绑定到用户输入的数据。请注意,bind_param仅将数据绑定到占位符,而保留查询不变。因此,没有办法更改原始SQL查询,因为它已经通过prepare方法发送到服务器,并且因为您是分别发送SQL查询和输入数据,所以用户输入的数据不会干扰查询。

无论如何...

在SQL中使用准备好的语句的实际目的是减少处理查询的成本,而不是将数据与查询分开。这就是现在的用法,而不是最初设计时的用法。

'sssd'代表“字符串”,“字符串”,“字符串”和“双精度”。实际上:$ code是一个字符串,$ language是一个字符串,$ official是一个字符串,$ percent是一个双精度类型。

不推荐使用mysqli_real_escape_string,但不推荐使用mysql_real_escape_string(第一个是mysqlI,在这里我代表“改进”)。

© www.soinside.com 2019 - 2024. All rights reserved.