PHP计数器增量错误

3
当用户点击图片时,我希望将计数器加1。我编写了以下代码,但是出现了错误“警告:mysql_fetch_array()期望参数1为资源,但提供的是布尔值,在C:\ xampp \ htdocs \ tkboom \ includes \ core.php的第72行”。请问有人能够查看一下我哪里出错了吗?
实际上,我创建了两个PHP文件,一个用于增加计数器,另一个用于显示计数器。在core.php文件中,我编写了函数,用于显示计数器的文件称为view.php。
core.php
    function GenerateCount($id, $playCount) {
            global $setting;
            $counter_query = "SELECT hits FROM ava_games WHERE id=".$_GET['id']."";
            $counter_res = mysql_query($counter_query);
            while($counter_row = mysql_fetch_array($counter_res)){
               $counter = $counter_row['hits'] + 1;
               $update_counter_query = "UPDATE ava_games SET hits=".$counter." WHERE id=".$_GET['id']."";
               $playCount = mysql_query($update_counter_query);
               $playCount = $row['hits'];
            }
            return $playCount;

    // Get count END
    }

view.php

<?php

$sql = mysql_query("SELECT * FROM ava_games WHERE published=1 ORDER BY id desc LIMIT 30");
while($row = mysql_fetch_array($sql)) {

    $url = GameUrl($row['id'], $row['seo_url'], $row['category_id']);

    $name = shortenStr($row['name'], $template['module_max_chars']);

    $playRt = GenerateRating($row['rating'], $row['homepage']);

    $playCt = GenerateCount($row['id'], $row['hits']);


    if ($setting['module_thumbs'] == 1) {
        $image_url = GameImageUrl($row['image'], $row['import'], $row['url']);

        $image = '<div class="homepage_game"><div class="home_game_image"><a href="'.$url.'"><img src="'.$image_url.'" width= 180 height= 135/></a></div><div class="home_game_info"><div class="home_game_head"><a href="'.$url.'">'.$name.'</a></div></div><div class="home_game_options"><img class="home_game_options_icon" src="'.$setting['site_url'].'/templates/hightek/images/joystick-icon.png" /> &nbsp;'.$playRt.' <b>|</b> '.$playCt.' plays &nbsp;</div></div>';
        echo $image;
    }



    }

?>

你是否在 $_GET['id'] 中获取到了值? - Arfeen
5个回答

4

这很可能意味着 SQL 语句存在错误。您可以通过 mysql_error() 获取有关错误的更多信息。
最简单的形式如下:

$counter_res = mysql_query($counter_query) or die(mysql_error());

(编辑:……这种方法虽然最简单,但是你不给应用程序处理问题的机会,“die”就像“死亡”一样。并且mysql_error()也可能泄露太多信息给您的WebService/网站用户,详见https://www.owasp.org/index.php/Top_10_2007-Information_Leakage_and_Improper_Error_Handling)

你的代码也容易受到以下问题的影响:

  • SQL注入攻击,因为在未经过任何净化处理的情况下将$_GET参数放入语句中。
  • 竞态条件,因为你有一个由一个SELECT和一个UPDATE组成的复合操作,没有任何锁定机制。

1

毕竟,这个查询看起来不太好。第一点:为什么要使用两个查询来增加一个值?UPDATE ava_games SET hits=hits+1 WHERE id=".$_GET['id'].""应该可以一步完成。第二点:你听说过SQL注入吗?转义或强制转换$_GET['id']以避免意外惊喜 ;)


1

这是因为您在SQL查询中出现了错误。
我会稍微修改一下:

$counter_query = 'SELECT hits FROM ava_games WHERE id = ' . (int)$_GET['id'];

确保您始终将id与整数值进行比较。


0
如果mysql_query返回布尔值,则表示查询失败。
假设id是主键,您可以使用以下函数在数据库级别上进行更新,从而防止竞态条件:
function GenerateCount($playCount) {
    global $setting;
    $update_counter_query = "UPDATE ava_games SET hits=hits + 1 WHERE id=".intval($_GET['id'])."";
    mysql_query($update_counter_query) or die(mysql_error());
    $counter_query = "SELECT hits FROM ava_games WHERE id=".intval($_GET['id'])." LIMIT 1";
    list($playCount) = mysql_fetch_row(mysql_query($counter_query));
    return $playCount;

// Get count END
}

还要注意在 $_GET 变量周围使用 intval() 来防止 SQL 注入


0

首先将值转换为 int 类型,如下所示:

function GenerateCount($playCount) {
    global $setting;
        $counter_query = "SELECT hits FROM ava_games WHERE id=".$_GET['id']."";
        $counter_res = mysql_query($counter_query);
        while($counter_row = mysql_fetch_array($counter_res)){
        $counter = intval($counter_row['hits']) + 1;
        $update_counter_query = "UPDATE ava_games SET hits=".$counter." WHERE id=".$_GET['id']."";
        $playCount = mysql_query($update_counter_query);
        $playCount = $row['hits'];
    }
    return $playCount;

// Get count END
}

并检查链接:

转换为整数


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