【问题标题】:php beginner question. if statementsphp初学者问题。 if 语句
【发布时间】:2009-07-09 03:33:48
【问题描述】:

检查一下,

我有这张桌子

表名:报告
身份证 (AI)
内容(varchar),
contentID (int),
检查(tinyint)

 if (isset($_GET['reportPost'])){

 $query = mysql_query("select * from reports where contentID = $_GET[reportPost]");
 $report = mysql_fetch_assoc($query);

 if (!mysql_num_rows($query) && $report['checked'] == 0) {
 echo 'There is already a pending report on this object.';
 } else {
 header("Refresh: 2; url=showthread.php?id=$id");
 echo '<div class="successMsg">Thanks for your report!</div>';
 mysql_query("insert into reports...");
 }

 }

我想用这段代码实现的是,如果报告中已经有记录 contentID = $_GET[reportPost] 并且 checked = 0 我不想要这要执行。上面的代码不会这样做。

一些帮助会很受欢迎:)

【问题讨论】:

  • 您的查询对 SQL 注入开放。在将 $_GET 和 $_POST 数据放入查询之前,您应该始终对其进行验证。
  • 或者正确地转义它——我们不要为 UPDATE、DELETE 和朋友执行 strstr() :-)

标签: php sql mysql


【解决方案1】:
  1. $_GET["reportPost"] 应该在字符串之外。我认为 PHP 不能正确地转义,无论如何,即使使用简单的变量也是不好的做法。你可能想这样做:

    $query = mysql_query("select * from reports where contentID = '" .mysql_real_escape_string($_GET[reportPost]) ."';"); 免费提供基本的 SQL 注入保护 :-)
  2. 您是否尝试验证我们是否未获取数据,然后尝试检查我们获取的内容?

     if (!mysql_num_rows($query) && $report['checked'] == 0) {
    看起来不对。正如其他人所建议的那样,要么将 && 替换为 ||,要么必须取消否定 (!)。

哦,顺便说一句,我建议你看看PDO。更实用,更容易切换到另一个数据库后端

编辑:我忘记在mysql_real_escape_string() 生成的字符串周围添加引号。我想我被 PDO 宠坏了,其中 $db->quote() 和参数化查询会自动执行此操作...

【讨论】:

  • To 1.:确实,PHP 看到 $_GET,然后是文字 '["reportPost"]'。但是,您可以使用这样的大括号:{$_GET['"reportPost"]}
  • 这仍然存在SQL注入问题,以及用单引号包围用户输入。除非输入已经在我们正在查看的代码块上方进行了清理:-)
【解决方案2】:

也许你应该试试:

 if (mysql_num_rows($query) && $report[0]['checked'] == 0) {

?

【讨论】:

  • 否定。 fetch_assoc 返回集合中的第一行。
【解决方案3】:

一些组合......

$query = mysql\_query("select * from reports where contentID = $\_GET[reportPost] AND checked<>0");
$report = mysql\_fetch\_assoc($query);

if (!mysql_num_rows($query) || $report['checked'] == 0) {
    echo 'There is already a pending report on this object.';
} else {
   ...
}

注意 WHERE 和 || 中的第二个子句而不是 &&

【讨论】:

    【解决方案4】:

    为什么不只是:

    $query = mysql_query("select * from reports where contentID = $_GET[reportPost] and checked = 0");
    $report = mysql_fetch_assoc($query);
    
    if (mysql_num_rows($query)) {
    echo 'This object is already been reported but not dealt  with.';
    } else {
    ....
    }
    

    【讨论】:

      【解决方案5】:

      我会将您的检查条件添加到 sql 语句中:

      $query = mysql_query("select * from reports where contentID = '" . $_GET[reportPost] . "' AND checked = 0");
      

      现在只有在检查结果时才会在结果中获得记录,因此您只需要测试对查询的响应中的行数。

      if (!mysql_num_rows($query)) {
      

      希望这会有所帮助。

      【讨论】:

      • 这仍然包含 SQL 注入缺陷,并且用户提交的字符串周围没有引号。更不用说在字符串中使用 {} 了:-)
      • 是的。为了安全起见,您需要使用引号。我更关注 had 中的问题,但你是对的,我已经纠正了你的观点。
      猜你喜欢
      • 2019-10-31
      • 2022-11-03
      • 2017-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多