【问题标题】:php: looping thru results from mysql query to increment counter (associative array)php:循环通过mysql查询的结果来递增计数器(关联数组)
【发布时间】:2011-11-22 22:27:58
【问题描述】:

我正在从 MySQL 数据库中检索数据并从中创建报告。当满足某些条件时,我需要获取计数,并且由于 db 查询相当昂贵(而且我将有很多流量),我循环遍历单个查询的结果以增加计数器。

似乎它正在工作(计数器正在递增)并且结果有点接近,但计数器不正确。

目前,表中有 411 条记录,但我从 ['total'] 计数器中获得了像 934 这样的数字,从 ['males'] 获得了像 927 这样的数字,这绝对不可能。但是,我从['females'] 得到 4,这是正确的……

我很确定昨晚它工作正常,但现在不行了——我很困惑。 (仍然只有 411 条记录)

$surveydata = mysql_query("SELECT `age`,`e_part`,`gender` FROM $db_surveydata;") or die(mysql_error());
$rowcount = mysql_num_rows($surveydata);
$age=array('18+'=>0,'<18'=>0,'total'=>0);
$e_part=array('yes'=>0,'no'=>0,'total'=>0);
$genders=array('male'=>0,'female'=>0,'trans'=>0,'don\'t know'=>0,'total'=>0);

while ($responses = mysql_fetch_assoc($surveydata)) {
    foreach ($responses as $response){
        switch ($response){
            case $responses['age']:
                if ($responses['age'] > 18) {$age['18+']++;$age['total']++;}
                // i tried putting the ['total'] incrementer in the if/else
                // just in case, but same result
                else {$age['<18']++;$age['total']++;}
                break;
            case $responses['e_part']:
                if ($responses['e_part']) {$e_part['yes']++;}
                else {$e_part['no']++;}
                $e_part['total']++;
                break;
            case $responses['gender']:
                switch ($responses['gender']){
                    case 1:$genders['male']++;break;
                    case 2:$genders['female']++;break;
                    case 3:$genders['trans']++;break;
                    case 9:$genders['don\'t know']++;break;
                    default:break;
                }
                $genders['total']++;
                break;
            default:break;
        } // end switch
    } //end for
} // end while

谢谢!

【问题讨论】:

  • 尝试在代码中插入一些调试语句,以缩小问题范围。

标签: php mysql loops switch-statement associative-array


【解决方案1】:

这就是问题所在:

foreach ($responses as $response){
        switch ($response){
            case $responses['age']:

switch $responses 寻找匹配项

foreach ($responses as $k=>$v){
    switch ($k){
        case 'age':
            if ($v > 18) ....

【讨论】:

  • 啊!天才(而且干净得多)。谢谢!!
  • '清洁工'?我认为让$v 成为一个年龄、一个e_part 或一个性别——都在同一个循环中——非常混乱。 :P 也就是说,它确实解决了 foreach 损坏的问题。
  • 这不是一个建议,只是一个错误修复。我不会迭代 $response,因为所有情况都被不同地对待(因此它不会节省代码)。
【解决方案2】:

mysql_fetch_assoc() 从表中检索单行。然后循环遍历该行,处理每个单独的字段。然后一长串if() 检查以确定您所在的字段。整个结构可以更改为:

while($response = mysql_fetch_assoc($surveydata)) {
    if ($responses['age'] > 18) {
        $age['18+']++;
    } else {
        $age['<18']++;
    $age['total']++;}

    if ($responses['e_part']) {
        $e_part['yes']++;
    } else {
        $e_part['no']++;
    }
    $e_part['total']++;

    switch ($responses['gender']){
        case 1:$genders['male']++;break;
        case 2:$genders['female']++;break;
        case 3:$genders['trans']++;break;
        case 9:$genders['don\'t know']++;break;
        default:break;
    }
    $genders['total']++;
}

【讨论】:

  • 嗨,Marc,['total']s 的放置看起来很麻烦:它们不是每个循环都会增加吗?另外,我尽量避免使用一系列 if 语句,因为当“太多”时,我遇到了不/不恰当地激活它们的问题(完全有可能是我的错,但尽管如此,我还是尽量避免这样做)。
  • 如果他们在不应该激活的时候激活,反之亦然,问题几乎可以肯定是对条件和/或您正在测试的值的误解。 switch 在不需要的情况下完成后看起来很奇怪。也就是说,无论何时if 和/或else 都会更合适。
  • 您的查询检索每一行的年龄/e_part/gender 字段。因此,age total/e_part total/gender_total 的个人计数将等于检索到的行数。如果您允许未回答的问题并且只想计算已填写的答案,则必须执行if ($response['age'] !== '') { $age['total']++; } 类型的操作。
【解决方案3】:

不需要switch ($response);你不能真正打开这样的阵列。即使你可以,你得到的“值”也没有任何意义——我在想如果它真的有效,你打开的值要么是“数组”,要么是数组的长度。 (我忘记了 PHP 是如何将数组作为标量处理的。)

你会想要这样的东西......

$total = 0;
while ($response = mysql_fetch_assoc($surveydata))
{
    if (isset($response['age']))
    {
        ++$age[($response['age'] < 18) ? '<18' : '18+'];
        ++$age['total'];
    }
    if (isset($response['e_part']))
    {
        ++$e_part[($responses['e_part']) ? 'yes' : 'no'];
        ++$e_part['total'];
    }
    if (isset($response['gender']))
    {
        switch ($response['gender'])
        {
             case 1: ++$genders['male']; break;
             case 2: ++$genders['female']; break;
             case 3: ++$genders['trans']; break;
             case 9: ++$genders["don't know"]; break;
        }
        ++$genders['total'];
    }
    ++$total;
}

if (isset(...)) 的好处是,如果 'age'、'e_part' 或 'gender' 为空,则相应的计数代码将不会被激活。它的作用与您的代码大致相同,只是减去了令人尴尬的循环,并且减去了字段的计数,即使它为空,因为每一行都将具有相同的字段。

【讨论】:

    猜你喜欢
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2014-06-11
    • 2021-05-29
    • 1970-01-01
    • 2014-11-17
    • 1970-01-01
    相关资源
    最近更新 更多