如果同一组多重结果,则mysqli结果循环

时间:2016-02-18 20:11:58

标签: php mysqli

我正在构建一个包含事件的日历,现在在生成数周的时间内,脚本连接到数据库并从那里获取事件信息。

它假设显示每天在数据库中有事件的事件,工作正常,但是当你在同一天有多个事件时,它只显示当天的一个事件。

如果我只是回显$ cellContent而不是显示所有事件。 如果我使用return $ cellContent(进一步生成和放置到html日历的日子),它将仅显示每天有事件的1个事件。

例如,有5个事件,本月22日为“A”事件,24日为“B”,第28位为“C”,第28位为“D”,第28位为“E”,脚本将显示只有ABC活动。

有什么建议吗?请举例说明

public function show() {
      $year = null;
      $month = null;
      $year = date("Y", time());
      $month = date("m", time());

      $this->currentYear = $year;
      $this->currentMonth = $month;
      $this->daysInMonth = $this->_daysInMonth($month, $year);
      $content = '<div id="calendar">' . "\r\n" . '<div class="calendar_box">' . "\r\n" . $this->_createNavi() . "\r\n" . '</div>' . "\r\n" . '<div class="calendar_content">' . "\r\n" . '<ul class="calendar_label">' . "\r\n" . $this->_createLabels() . '</ul>' . "\r\n";
      $content .= '<div class="calendar_clear"></div>' . "\r\n";
      $content .= '<ul class="calendar_dates">' . "\r\n";
      $weeksInMonth = $this->_weeksInMonth($month, $year);
      // Create weeks in a month
      for ($i = 0; $i < $weeksInMonth; $i++) {
        //Create days in a week
        for ($j = 1; $j <= 7; $j++) {
          $content .= $this->_showDay($i * 7 + $j);
        }
      }
      $content .= '</ul>' . "\r\n";
      $content .= '<div class="calendar_clear"></div>' . "\r\n";
      $content .= '</div>' . "\r\n";
      $content .= '</div>' . "\r\n";
      return $content;
    }
private function _showDay($cellNumber) {
      if ($this->currentDay == 0) {
        $firstDayOfTheWeek = date('N', strtotime($this->currentYear . '-' . $this->currentMonth . '-01'));
        if (intval($cellNumber) == intval($firstDayOfTheWeek)) {
          $this->currentDay = 1;
        }
      }
      if (($this->currentDay != 0) && ($this->currentDay <= $this->daysInMonth)) {
        $this->currentDate = date('Y-m-d', strtotime($this->currentYear . '-' . $this->currentMonth . '-' . ($this->currentDay)));
        $cellContent = $this->currentDay;
        $this->currentDay++;
      } else {
        $this->currentDate = null;
        $cellContent = null;
      }
      $today_day = date("d");
      $today_mon = date("m");
      $today_yea = date("Y");
      $class_day = ($cellContent == $today_day && $this->currentMonth == $today_mon && $this->currentYear == $today_yea ? "calendar_today" : "calendar_days");

    $servername = "localhost";
    $username = "root";
    $password = "root";
    $dbname = "test";

    // Create connection
    $conn = new mysqli($servername, $username, $password, $dbname);
    // Check connection
    if ($conn->connect_error) {
         die("Connection failed: " . $conn->connect_error);
    } 

    $sql = "SELECT owner, title, opening FROM _sites
            WHERE YEAR(opening) = $today_yea AND MONTH(opening) = $today_mon";
    $result = $conn->query($sql);

    if ($result->num_rows > 0) {
     while($row = $result->fetch_assoc()) {
             $dfd = $row['opening'];
             $dfd = explode("-", $dfd );
                    if ($cellContent == $dfd[2] && $this->currentMonth == $dfd[1] && $this->currentYear == $dfd[0]){
                        $class_day = "calendar_event";
                        $cellContent = '<a href="#">' . $cellContent . '</a><div>';
                        $cellContent = $cellContent .'<a href="' . $row['owner'] . '">' . $row['title'] . '</a><br>' . $row['opening'] . '<hr>';
                        $cellContent = $cellContent . '</div>';
                    }
         }
    } else {
         echo "0 results";
    }
    $conn->close();

      return '<li class="' . $class_day . '">' . $cellContent . '</li>' . "\r\n";
    }

1 个答案:

答案 0 :(得分:1)

您可以使您的功能更简单。首先,修改您的for循环以使用天而不是几周,并改善您的数据库连接逻辑:

// No need to connect to DB every time you call the _showDay().
// Just do it once (create a private variable $this->conn).
$servername = "localhost";
$username = "root";
$password = "root";
$dbname = "test";

// Create connection
$this->conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($this->conn->connect_error) {
     die("Connection failed: " . $this->conn->connect_error);
}

// $weeksInMonth = $this->_weeksInMonth($month, $year);
// Remove the line above and add this instead:
$daysInMonth = date("t");
for ($i = 1; $i <= $daysInMonth; $i++) {
    $content .= $this->_showDay($i);
}
// And the rest of your code...
$content .= '</ul>' . "\r\n";

然后,您修改_showDay()函数,删除不必要的检查:

private function _showDay($day) {
    $today_day = date("d");
    $class_day = ($day == $today_day ? "calendar_today" : "calendar_days");

    // Build a date in YYYY-MM-DD format and pass it over into SQL
    $currentDate = $this->currentYear .'-'. $this->currentMonth .'-'. str_pad($day, 2, '0', STR_PAD_LEFT);
    $sql = "SELECT owner, title, opening FROM _sites
            WHERE DATE(opening) = '". $currentDate ."'";
    $result = $this->conn->query($sql);

    // No need to do anything else if nothing is happening on this day.
    if (empty($result->num_rows)) {
        $conn->close();
        return '<li class="' . $class_day . '">0 results</li>' . "\r\n";
    }

    // Otherwise, build the content.
    // Let's not clutter the code with endless concatenation and
    // use output buffering and echo statements instead.
    ob_start();
    while($row = $result->fetch_assoc()) {
        echo '<a href="#">' . $day . '</a><div>';
        echo '<a href="' . $row['owner'] . '">' . $row['title'] . '</a><br>' . $row['opening'] . '<hr>';
        echo '</div>';
    }
    $conn->close();
    return '<li class="calendar_event">' . ob_get_clean() . '</li>' . "\r\n";
}

整个逻辑可以(并且应该)进行更多优化 - 例如,仅使用一个SQL查询一次返回所有事件,按日期分组,并将结果传递给_showDay(),但我认为这应该做现在。