【问题标题】:Show year only once in archives loop在档案循环中仅显示一次
【发布时间】:2012-03-04 09:57:45
【问题描述】:

我刚开始使用 PHP 和 mySQL,我正在创建某种博客。有时我认为它进展顺利 - 我的档案代码遇到了一些问题。

我认为解决方案会很简单,但我太盲目了,我自己找不到重点。

这是我的实际代码,一切正常,链接也是:

$sql = mysql_query ("SELECT YEAR(date) AS get_year, MONTH(date) AS get_month, COUNT(*) AS entries FROM blogdata GROUP BY get_month ORDER BY date ASC") or die('No response from database.');


while ($row = mysql_fetch_array($sql)) {

$get_year = $row["get_year"];
$get_month = $row["get_month"];
$entries = $row["entries"];

    // get month name
$this_month = date( 'F', mktime(0, 0, 0, $row["get_month"]) );



echo '<dl>';
echo '<dt>Entries from &nbsp;'. $get_year . '</dt>';

echo '<dd><a href="archives.php?month='. $get_month .'">Entries from &nbsp;'. $this_month . '&nbsp;</a>(' . $entries . ')</dd>';

echo '</dl>';  

}

好的。然后在浏览器中的结果看起来是这样的:

  • 2012 年的参赛作品
    1. 1 月 (2) 月的参赛作品
  • 2012 年的参赛作品
    1. 2 月的参赛作品 (1)

现在我的问题是:如何恢复一年中的所有月份?像这样:

  • 2012 年的参赛作品
    1. 1 月 (2) 月的参赛作品
    2. 2 月的参赛作品 (1)

我害怕创建一个 12 个月的数组,因为可能不是每个月都会有条目,而且我不想显示空月份。

有人可以帮助我吗?谢谢!!

---------------

在这里,我再次展示您友好帮助的最终(工作!!)结果:

至少,我使用了 Sam 的版本,因为它正是我想要的。我真的很感谢其他答案 - 特别是因为现在我有更多的东西要考虑下一次尝试。

Sam 的代码工作得非常棒......我唯一遇到的问题是,在使用数组后,它只打印出 'December' 作为几个月。

于是我再次查看了代码,经过 2 个小时的寻找和尝试,我发现了问题所在。它嵌套在以下行中:

$this_month = date( 'F', mktime(0, 0, 0, $row['get_month']) );

将其更改为:

$this_month = date( 'F', mktime(0, 0, 0, $month['get_month']) );

现在一切正常。正是我所期望的。所以这是工作的最终代码:

    $sql = mysql_query ("SELECT YEAR(date) AS get_year, MONTH(date) AS get_month, COUNT(*) AS entries FROM blogdata GROUP BY get_year, get_month ORDER BY date ASC") or die('No response from database.');


    $entries = array();
    while ($row = mysql_fetch_assoc($sql)) {
    $entries[$row['get_year']][] = $row;
}

    foreach($entries as $year => $months) {
  echo '<dl>';
  echo '<dt>Entries from &nbsp;'. $year . '</dt>';


    foreach($months as $month) {
    $this_month = date( 'F', mktime(0, 0, 0, $month['get_month']) );

  echo '<dd><a href="archives.php?month='. $month['get_month'] .'">Entries from &nbsp;'. $this_month . '&nbsp;</a>(' . $month['entries'] . ')</dd>';

  }

  echo '</dl>';


}

再次感谢大家!

【问题讨论】:

    标签: php mysql date loops blogs


    【解决方案1】:

    我发现最简单的方法是这样的:

    $entries = array();
    while ($row = mysql_fetch_assoc($sql)) {
      $entries[$row['get_year']][] = $row;
    }
    
    foreach($entries as $year => $months) {
      echo '<dl>';
      echo '<dt>Entries from &nbsp;'. $year . '</dt>';
    
      echo '<dd>';
      foreach($months as $month) {\
        $this_month = date( 'F', mktime(0, 0, 0, $row["get_month"]) );
    
        echo '<a href="archives.php?month='. $month['get_month'] .'">Entries from &nbsp;'. $this_month . '&nbsp;</a>(' . $month['entries'] . ')';
      }
      echo '</dd></dl>';
    
    
    }
    

    HTML 标记并不理想,但您应该明白。

    【讨论】:

    • 天哪,就是这样:D 我自己在 foreach 中跌跌撞撞,但我没有找到正确的关联。非常感谢您的快速回答!
    • 顺便说一句 - Safka 是对的,您还需要按年份分组。否则,您会将所有年份的每个日历月的条目混合在一起。
    • 再次感谢!我将检查其他代码并尝试找到一个可以稍微清理我的代码的好的解决方案。非常有帮助,伙计们!
    • 当该月的某一天在 28 日之后,date('F', mktime(0, 0, 0, $row["get_month"]) ) 将返回 'March',即使$row["get_month"] 的值为 2。要修复它,请将其更改为 date('F', mktime(0, 0, 0, $month['get_month'], 1) )
    【解决方案2】:

    首先将您的查询更改为按年和月分组,而不仅仅是按月:

    $query = "SELECT 
        YEAR(date) AS get_year, 
        MONTH(date) AS get_month, 
        COUNT(*) AS entries 
    FROM blogdata 
    GROUP BY get_year, get_month 
    ORDER BY date ASC"
    

    我不记得旧的 mysql API,所以这是带有 PDO 的代码(未经测试,但在修复潜在的错别字后应该可以工作)

    $pdo = new PDO('mysql:host=localhost;dbname=db', 'user', 'password');
    $stmt = $pdo->prepare($query);
    $stmt->execute();
    
    $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
    
    //group results by year *
    $groupped = array();
    foreach ($results as $record) {
        $groupped[$record['get_year']] = $record;
    }
    
    //print results
    echo "<dl>";
    foreach ($groupped as $year => $monthsRecords) {
        echo "<dt>$year</dt>";
        foreach ($monthsRecords as $record) {
            echo "<dd>{$record['get_month']} : {$record['entries']}</dd>";
        }
    } 
    echo "</dl>";
    

    您还可以尝试使用 PDO::FETCH_GROUP 来简化代码,如中所述 fetchAll method doc 但我没试过这个,所以我不会给你代码。

    【讨论】:

    • 谢谢,我会实现查询更正并进一步查看您的代码。非常感谢。 :)
    • 非常感谢您也提供了将 get_year 分组的提示。我会监督这一点并想知道明年谢谢:)
    • “明年会出现的错误”是我最喜欢的 ;) 也许除了“只会在闰年出现的错误”
    • 我想知道完成这个项目后我还会发现多少“错误”^^
    【解决方案3】:

    试试这个

    $start_year =  date("Y")-10;
    $end_year = date("Y");
    for ($i=$start_year;$i<$end_year;$i++){
     $sql = mysql_query ("SELECT YEAR(date) AS get_year, MONTH(date) AS get_month, COUNT(*)    AS entries FROM blogdata where YEAR(date) = $i GROUP BY get_month ORDER BY date ASC"); or die('No response from database.');
       //execute your query here. get the 
        $result = mysql_query($sql);
          echo '<dl>';
        echo '<dt>Entries from &nbsp;'. $i . '</dt>';
    
       while ($row = mysql_fetch_array($result )) {
    
           $get_year = $row["get_year"];
           $get_month = $row["get_month"];
            $entries = $row["entries"];
    
     // get month name
     $this_month = date( 'F', mktime(0, 0, 0, $row["get_month"]) );
    
      echo '<dd><a href="archives.php?month='. $get_month .'">Entries from &nbsp;'.   $this_month .  '&nbsp;</a>(' . $entries . ')</dd>';
    
     }
       echo '</dl>';
    }
    

    【讨论】:

    • 也感谢您提供另一个解决方案:D 我知道我明天有很多事情要做,看看这一切,呵呵。
    猜你喜欢
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多