当我通过电子邮件地址选择时,为什么会出现MySQL语法错误(1604)?

时间:2016-11-15 06:59:27

标签: php mysql

我将PHP中的电子邮件地址与MySQL数据库进行比较:

$query
    ->select(array('a.dtstart','a.cal_id','b.name','a.email'))
    ->from('#__pbbooking_events AS a')
    ->join('INNER', '#__pbbooking_cals AS b ON (a.cal_id = b.id)')
    ->where('a.email =  ' . $user->email)
    ->where(' a.dtstart>'. $query->currentTimestamp()) 
    ->order('a.dtstart ASC'); 

$user只包含当前登录用户的信息。

我收到此错误

  

您的SQL语法中存在错误;检查手册   对使用MARYADB服务器版本的正确语法的使用说明   在第4行附近@RET.RU AND A.DTSTART>CURRENT_TIMESTAMP() ORDER BY A.DTSTART ASC

如果我删除了比较电子邮件的where子句,则查询运行时没有错误。

我在某处读到问题是@符号,但我怎么能进行这种比较?

2 个答案:

答案 0 :(得分:1)

你必须把它放在引号中:

->where('a.email = "' . $user->email.'"')

请注意,您需要转义该电子邮件地址。这取决于您正在使用的SQL库。一个老例子是这样的:

->where('a.email = "' . mysql_real_escape_string( $user->email ).'"')

为什么'老'?

really 应该using prepared statements而不是转义。我会假设您使用的库支持它们,但我不能肯定地说。如果没有,您应该考虑删除它并按照previous link中的解决方案。

实际发生了什么?

您的查询是这样的:

where a.email=hello@site.com and a.dtstart>342734..

SQL将电子邮件视为查询的一部分。这是所谓的SQL注入攻击的基础。例如,假设电子邮件设置为:

"" or (drop table users)

使您的查询如下所示:

where a.email="" or (drop table users) and a.dtstart>342734..

..这可能会导致一些重大问题!不要相信来自用户的任何信息。

答案 1 :(得分:-1)

$user->email是字符串,因此您需要在电子邮件中使用'个单括号。

尝试以下

$query
    ->select(array('a.dtstart','a.cal_id','b.name','a.email'))
    ->from('#__pbbooking_events AS a')
    ->join('INNER', '#__pbbooking_cals AS b ON (a.cal_id = b.id)')
    ->where("a.email = '" . $user->email. "'") // $user->email is string
    ->where(' a.dtstart > '. $query->currentTimestamp())
    ->order('a.dtstart ASC');