如果没有启用magic_quotes_gpc(它们不应该启用,魔术引号是PHP的众多设计错误之一,现在已被弃用),黑客(或者很可能是机器人!)可以随意更改您的查询,从而导致各种麻烦到您的网站。
解决这个严重问题的正确方法是使用准备好的语句,例如使用 PDO。或者,您可以使用 mysql_real_escape_string:
$sql = "SELECT COUNT(*) FROM oneliners WHERE to_user='" .
mysql_real_escape_string($username_me) . "' AND `read`=0";
麻烦mysql_real_escape_string
在于您必须记住始终使用它,而使用准备好的语句可以解决这些问题。此外,如果您没有使用准备好的语句,您可以使用它intval
来清理您的整数输入。
让我再次强调一下:清理您的输入非常重要。你不应该相信来自用户的任何东西。
您的问题是由 mysql_query 在查询失败时返回 FALSE 引起的。如果查询失败,mysql_query返回 FALSE 而不是 resource。您可以在资源上调用 mysql_num_rows,而不是在 FALSE 上。(来自手册:mysql_query() 成功时返回资源,错误时返回 FALSE)。
该错误是由read
字段名称引起的,因为它是一个保留字。尝试用反引号 (`) 引用它,或者更好的是,重命名它。
要找出一行是否存在,您可以使用COUNT(*)
或SELECT 1
查询将COUNT
始终返回 0 或 1 的值(我想您在 上有一个唯一索引to_user
),当然查询失败时除外。
$sql = "SELECT COUNT(*) FROM oneliners WHERE to_user='" .
mysql_real_escape_string($username_me) . "' AND `read`=0";
如果该SELECT 1
行存在,查询将返回 1,否则它不会返回任何行。
$sql = "SELECT 1 FROM oneliners WHERE to_user='" .
mysql_real_escape_string($username_me) . "' AND `read`=0 LIMIT 1";
使用哪一个取决于您是需要行数还是只需要知道行是否存在。如果存在唯一索引,则无论如何它们在计算上应该非常相似。