2010-04-22 91 views
119

我有一个令人困惑的问题,我似乎无法理解...我希望这里有人能够指引我朝着正确的方向...在PHP中插入MySQL时转义PHP中的单引号

我有两条SQL语句: - 第一条从表单中输入信息到数据库中。 - 第二个从上面输入的数据库中获取数据,发送电子邮件,然后记录交易的详细信息

问题是,它似乎是一个单引号只触发第二个条目上的MySQL错误! !第一个实例没有问题,但第二个实例触发mysql_error()

来自表单的数据是否得到与表单中捕获的数据不同的处理?

查询#1 - 这工作没有问题(并且没有逃逸单引号)

$result = mysql_query("INSERT INTO job_log 
(order_id, supplier_id, category_id, service_id, qty_ordered, customer_id, user_id, salesperson_ref, booking_ref, booking_name, address, suburb, postcode, state_id, region_id, email, phone, phone2, mobile, delivery_date, stock_taken, special_instructions, cost_price, cost_price_gst, sell_price, sell_price_gst, ext_sell_price, retail_customer, created, modified, log_status_id) 
VALUES 
('$order_id', '$supplier_id', '$category_id', '{$value['id']}', '{$value['qty']}', '$customer_id', '$user_id', '$salesperson_ref', '$booking_ref', '$booking_name', '$address', '$suburb', '$postcode', '$state_id', '$region_id', '$email', '$phone', '$phone2', '$mobile', STR_TO_DATE('$delivery_date', '%d/%m/%Y'), '$stock_taken', '$special_instructions', '$cost_price', '$cost_price_gst', '$sell_price', '$sell_price_gst', '$ext_sell_price', '$retail_customer', '".date('Y-m-d H:i:s', time())."', '".date('Y-m-d H:i:s', time())."', '1')"); 

查询#2 - 用单引号(即奥布莱恩)

输入姓名时,该故障
$query = mysql_query("INSERT INTO message_log 
(order_id, timestamp, message_type, email_from, supplier_id, primary_contact, secondary_contact, subject, message_content, status) 
VALUES 
('$order_id', '".date('Y-m-d H:i:s', time())."', '$email', '$from', '$row->supplier_id', '$row->primary_email' ,'$row->secondary_email', '$subject', '$message_content', '1')"); 

回答

85

您应该使用mysql_real_escape_string()转义每个字符串(在这两个片段中)。

http://us3.php.net/mysql-real-escape-string

你两个查询行为不同的原因可能是因为你有magic_quotes_gpc开启(你应该知道是一个坏主意)。这意味着从$ _GET,$ _POST和$ _COOKIES收集的字符串会被转义(即"O'Brien" -> "O\'Brien")。

一旦你存储了数据,然后再次检索它,你从数据库中取回的字符串将会自动从你的而不是中逃脱。你会回到"O'Brien"。所以,你需要通过mysql_real_escape_string()

+0

呀好,感谢在正确编码的教训然而,这并没有回答为什么这两个查询不抛出同样的错误问题... – sjw 2010-04-22 03:01:26

+0

我不在寻找如何解决它的答案 - 我知道如何解决它。我正在寻找“为什么”! – sjw 2010-04-22 03:02:36

+1

这不是一个*正确*编码的问题,这是一个空洞和危险的安全漏洞问题。话虽如此,我会在我的原始答案中添加一段代码来说明潜在的问题。我会在这里做,但格式化将是所有的。 :) – awgy 2010-04-22 03:08:17

9

你应该做这样的事情来帮助您调试

$sql = "insert into blah blah...."; 
echo $sql; 

你可能会发现,单引号逃脱在工作查询反斜杠。这可能是由php通过magic_quotes_gpc设置自动完成的,也可能是你自己在代码的其他部分完成的(addslashes和stripslashes可能是需要查找的函数)。

http://php.net/manual/en/security.magicquotes.php

9

你有几件事情在你的字符串战斗。

  • 缺乏正确的MySQL引用的(mysql_real_escape_string()
  • 潜在自动“魔术引号” - 检查你的gpc_magic_quotes设置
  • 嵌入式字符串变量,这意味着你必须知道如何PHP正确认定变量

单引号值也可能不存在于第一个查询的参数中。毕竟,你的例子是一个合适的名字,只有第二个查询似乎在处理名称。

-3

我有同样的问题,我解决了它这样的:

$text=str_replace("'","\'",$YourContent); 

有可能是一个更好的方式来做到这一点,但它的工作对我来说,它应该为你工作了。

+0

有一个更好的方法...比这个任何其他人。严重的是,如果你不想让你的数据库获得Bobby Table,那么不要这样做。使用PDO(正确的方式) - 它会照顾你逃跑。甚至使用不推荐使用的'mysql_real_escape_string'(不正确的方法)!或'addslashes'(不正确的方式)。除此之外的任何东西。 – 2013-08-13 14:31:23

+0

您应该为此执行本机功能。 – 2016-11-05 17:48:51

6

你应该只传递变量或数据里 “mysql_real_escape_string(修剪($ VAL))”

其中$ VAL =这是困扰你的数据。

9

您可以执行以下操作,同时转义PHP和MySQL。

<? 
$text = '<a href="javascript:window.open(\\\'http://www.google.com\\\');"></a>'; 
?> 

这将反映MySQL作为

<a href="javascript:window.open('http://www.google.com');"></a> 

它是如何工作的?

我们知道这两个PHP和MySQL省略号可以用反斜杠,然后撇号进行转义。

\' 

因为我们使用PHP插入到MySQL,我们需要PHP仍然写反斜杠到MySQL所以它也能够逃脱它。 因此,我们使用反斜杠反斜杠的PHP转义字符和反斜杠撇号来实现此目的。

\\\' 
33

对于任何人在2015年发现这个解决方案和前进......

mysql_real_escape_string()功能被弃用PHP 5.5.0的。

参见:php.net

警告

这个扩展不赞成PHP 5.5.0的,并会在将来被移除。相反,应该使用MySQLi或PDO_MySQL扩展。另请参阅MySQL:选择API指南和相关FAQ以获取更多信息。替代该功能包括:

mysqli_real_escape_string()

PDO::quote()

+2

mysqli_real_escape_string需要2个参数它说 – coolcool1994 2015-06-12 03:35:21

+0

@ coolcool1994 - 我也有这个问题,直到我发现这个问题 - http://stackoverflow.com/questions/25636975/warning-mysqli-real-escape-string-expects-完全是2参数1给定wh。 看起来,mysqli _ **()函数需要第一个参数为您的mysqli数据库连接变量(我通常将其命名为“$ conn”)。 – RoboBear 2016-03-21 23:47:40

+0

@ coolcool1994 - 是的,你需要你的连接字符串以及你逃跑的东西。对于很多用户来说,这将是'$ con'或'$ conn'。 – 2017-02-23 17:31:06