PHP MySQL 遍历行并在日期更改时打印日期

PHP MySQL loop through the rows and print date when the date changes

我的messagestable是这样的:

id : (auto increment)
incoming_msg_id : (receiver's user id, BIGINT)
outgoing_msg_id : (sender's user id, BIGINT)
msg : (message content, LONGTEXT)
created_at : (timestamp)

这是我用于获取消息的查询:

$stmt = $pdo->prepare("SELECT * FROM messages
                       LEFT JOIN users ON users.id = messages.outgoing_msg_id
                       WHERE (outgoing_msg_id = :omsg AND incoming_msg_id = :imsg) OR (outgoing_msg_id = :imsg AND incoming_msg_id = :omsg)
                       ORDER BY messages.id ASC");
$stmt-> bindValue(':imsg', $imsg);
$stmt-> bindValue(':omsg', sessionUser());
$stmt-> execute();

我想使用 created_at 时间戳字段以这种方式对消息进行分组,以便我可以在消息交易发生时显示 date

例如:

5th July, 2021

Message 1
Message 2

6th July, 2021

Message 3
Message 4

因此,我想在每次日期更改时打印一个包含日期的新 header。我当前的 PHP 循环是这样的:

while($f = $stmt->fetch()){

  // HERE, I WANT TO CHECK IF DATE CHANGES AND PRINT A NEW HEADER, FOR EXAMPLE
  // if(dateChanges){ echo date('jS M, Y', strtotime($f['created_at'])); } // UNSURE, OF LOGIC INSIDE IF STATEMENT

  if($f['outgoing_msg_id'] == sessionUser()){
    $html .= "<div class='chat outgoing'>
                <div class='details d-flex'>
                  <div class='textmsgbox'>
                    <div class='thechatmsg'>".decrypt($f['msg'], ENCRYPTION_KEY)."</div>
                    <div class='tmbcontent d-flex'>
                      <small>".date('h:i a', strtotime($f['created_at']))."</small>
                      <small class='seen'>$seen</small>
                    </div>
                  </div>
                </div>
              </div>";
  }else{
    $html .= "<div class='chat incoming'>
                <div class='details d-flex'>
                  <div class='textmsgbox'>
                    <div class='thechatmsg'>".decrypt($f['msg'], ENCRYPTION_KEY)."</div>
                    <div class='tmbcontent'>
                      <small>".date('h:i a', strtotime($f['created_at']))."</small>
                    </div>
                  </div>
                </div>
              </div>";
  }
}

很简单。首先,您需要在循环外声明一个 null 变量,然后对照它检查时间戳的日期并打印日期。然后在最后,您可以使用时间戳中的日期更新先前定义的 null 变量,您就完成了。看看下面的代码:

$lastDate = null; // DECLARE A NULL VARABLE FOR THE LAST DATE
while($f = $stmt->fetch()){
  $chatDate = null; // DECLARE A NULL VARIABLE HERE TO AVOID MULTIPLE OUTPUTS
  
  // CHECK AGAINST THE LAST DATE IF IT EQUALS TO THE TIMESTAMP'S DATE, IF NOT, PRINT THE DATE
  if($lastDate !== date('Y-m-d', strtotime($f['created_at']))) {

    // I ADDED THIS ADDITIONAL CODE SO THAT YOU CAN PRINT THE DATE AS "TODAY" & "YESTERDAY" 
    // You may remove this if you don't want

    if(date('Y-m-d', strtotime($f['created_at'])) == date('Y-m-d')){
      $cd = "TODAY";
    }else if(date('Y-m-d', strtotime($f['created_at'])) == date('Y-m-d', strtotime('-1 day'))){
      $cd = "YESTERDAY";
    }else{
      $cd = date('jS F, Y', strtotime($f['created_at']));
    }

    $chatDate = "<div class='chat-date'>".$cd."</div>";
  }

  $html .= $chatDate;

  // YOUR IF....ELSE CONDITION GOES HERE
  if(){
    // Your code as in question
  }else{
    // Your code as in question
  }

  // UPDATE THE NULL VARIABLE WITH CURRENT DATE
  $lastDate = date('Y-m-d', strtotime($f['created_at'])); 
}

完成!就如此容易。享受:)