我应该使用mysqli_real_escape_string()还是mysql_real_escape_string()来处理表单数据?

12

可能是重复问题:
mysql_escape_string VS mysql_real_escape_string

我需要把用户在表单中输入的 company_name 存储到我的MySQL数据库中。 当我使用

$company = mysqli_real_escape_string($_POST['company_name'])

我遇到了一个错误

Warning: mysqli_real_escape_string() expects exactly 2 parameters, 1 given in     /opt/lampp/htdocs/Abacus-Version-2/admin/Company/insert_company.php on line 58

但是在使用时一切似乎都很好

$company = mysql_real_escape_string($_POST['company_name'])

在这种情况下我该做什么?


8
不理解重复投票的原因。那个“重复”的问题是关于escapereal_escape之间的区别,而这个问题则是关于mysqlmysqli之间的区别,它们都使用了real_escape - Oldskool
2
请勿在新代码中使用mysql_*函数。它们已不再维护,并已正式弃用。看到红框了吗?请学习prepared statements,并使用PDOMySQLi - 本文将帮助您决定选择哪个。如果您选择PDO,这是一个好的教程 - Madara's Ghost
@MadaraUchiha 他们已经在使用mysqli了。 - Your Common Sense
看起来不是这样的。如果他们正在使用“mysql_real_escape_string”并且有效,那么这意味着他们已经建立了一个ext/mysql连接。 - Madara's Ghost
6个回答

14

使用哪个取决于您是使用MySQLi扩展还是MySQL扩展

// procedural mysqli 
$db = new mysqli; 
$sql = sprintf("INSERT INTO table (id,name,email,comment) VALUES (NULL,'%s','%s','%s')", 
   mysqli_real_escape_string($db,$name), 
   mysqli_real_escape_string($db,$email), 
   mysqli_real_escape_string($db,$comment) ); 

// mysql 
$conn = mysql_connect(); 
$sql = sprintf("INSERT INTO table (id,name,email,comment) VALUES (NULL,'%s','%s','%s')", 
   mysql_real_escape_string($name,$conn), 
   mysql_real_escape_string($email,$conn), 
   mysql_real_escape_string($comment,$conn) );  

3
不行,现在不能再使用 mysql_* 了。 - Shoe
事实上,只要您的PHP版本低于5.5(即使在更高版本中也可以,但需要进行一些错误抑制),它们就可以自由使用。 - Your Common Sense
1
@YourCommonSense,不是的,它们只应该在PHP版本低于5.0的情况下使用,因为它们已经被弃用,而mysqli和PDO驱动程序已经在PHP 5.x中部署。 - Shoe
4
不,开发者可以自由选择使用mysql_*函数。仅当在5.5+中使用时,它才会产生E_DEPRECIATED警告。你最初的观点“不能使用”是不正确的 - 只是不建议使用它们。 - Jimbo
4
如果你想的话,你可以用脚来开车,但这并不代表这是个好主意。 - Chris Rock - Mr_Chimp

10

mysql_real_escape_string()旨在使数据插入数据库时不会出现错误,例如转义斜杠以避免破坏代码。

您应该使用mysql_mysqli_函数匹配您的连接字符串。"mysqli"是mysql函数集的面向对象实现,因此函数以面向对象的方式调用。而"mysql"是过程式的。我建议改用"mysqli",因为我相信未来版本中可能会废弃"mysql"函数。

如果您的连接字符串是:

mysql_connect()

然后使用:

mysql_real_escape_string($_POST[''])

如果它是:
$mysqli = new mysqli();

那么使用:

$mysqli->real_escape_string($_POST[''])

他正在将$_POST的值放入转义方法中。文件名为insert_company.php,因此很有可能他正在插入数据。 - Oldskool
糟糕,他把我搞混了,因为他说“我想要得到”。我已经更正了我的答案。 - Luke
3
哦,是这样吗?这就是为什么在手册中它这样说明的原因吗?“对未转义字符串进行特殊字符转义,考虑到连接的当前字符集,以便可以安全地将其放置在mysql_query()函数中。”http://php.net/manual/en/function.mysql-real-escape-string.php 阅读愉快! - Luke
请注意,此功能已被弃用。此扩展在PHP 5.5.0中已被弃用,并在PHP 7.0.0中被删除。 - Luke

3

绝对不行

这两个函数与表单数据无关。
它们必须用于仅格式化插入到SQL查询中的字符串文字
此函数属于SQL查询,而不是任何表单。甚至只属于查询的非常有限的部分 - 字符串文字。

因此,每次要将字符串文字(坦白地说,是用引号括起来的数据部分)插入查询中时,都应无条件使用此函数。
对于任何其他情况,都不应使用它。

至于您收到的错误 - 它非常自我解释:此函数需要2个参数,而不是一个。只需按照该函数的手册页面中所述传递正确的参数,您就可以正常运行了。


7
这并不是“非常容易理解的”-原帖作者显然对MYSQL函数的两种实现感到困惑。除非他已经实例化了这个对象,“mysqli”函数不会突然在传递两个参数时起作用。 - Luke
同意不必阅读文档就使用它的观点,但如果这里没有问题,我们应该关闭问题而不是回答。这并不是自我解释的,因为这是用户的问题。他们的问题在于区分“mysqli”和“mysql”函数。 - Luke

1

如果您使用过程式风格,应该是这样的:

$city = mysqli_real_escape_string($link, $city);

链接是连接的方式

当您使用面向对象的风格时,可以这样:

$city = $mysqli->real_escape_string($city);

请查看 PHP 手册: http://php.net/manual/zh/mysqli.real-escape-string.php


你读了这个问题吗? - Shoe
是的,他遇到了一个错误,所以我给了他一个解决方案。当您从数据库获取数据时,应始终将数据按其输入方式放入数据库中,然后使用类似htmlentities的东西格式化数据。 - Perry
我尝试了过程式的方法,但是得到的结果是一个空字符串。有什么建议吗? - Marian Klühspies

0

两种变体都可以*(请看我的更新)。

当您使用mysql_connect时,应坚持使用mysql_real_escape_string()并传递连接句柄。

当您使用mysqli_connect时,应坚持使用mysqli_real_escape_string()

更新

正如Jeffrey在评论中指出的那样,使用mysql_函数是不好的。我同意这一点。我只是指出,您需要使用由您正在使用的MySQL扩展使用的函数。

我想到了一个问题,那就是不是问你使用哪个MySQL扩展,而是要转义数据的功能是哪个。

如果您问我:

  • 使用 mysqliPDO,因为 mysql 不可推荐且已被弃用。
  • 将连接句柄传递给转义函数或更好的方法是
  • 使用 预处理语句 (PDO 风格)

1
Jeffrey,我回答了他的用例问题,但没有考虑到mysqli扩展的优势。我澄清了我的回答,希望现在更好了,这样我也可以帮助其他人。 - Stefan
这些函数不应用于转义“数据”。 - Your Common Sense
@steve,我知道,我看到了。事实上,我没有给你投反对票,那是一条必须留下来的评论,为了未来可能会被鼓励使用它们的访问者。 - Shoe

0

由于所有的 MySQL 扩展都已经弃用, 您最好使用 MySQLi 方法,这样更具有未来性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接