PHP MySQL перебирает строки и выводит дату при изменении даты

#php #mysql #sql #pdo #group-by

Вопрос:

Мой messages стол такой:

 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
 

Поэтому я хочу печатать новый заголовок, содержащий дату, каждый раз, когда дата меняется. Мой текущий цикл 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>";
  }
}
 

Комментарии:

1. Вам нужно сохранить дату текущей строки в переменной. Затем, в следующий раз, когда вы будете зацикливаться, вы сможете сравнить переменную с новой текущей датой и посмотреть, изменилась она или нет

2. @ADyson Я думаю, что ответ Шрейанша Кашьяпа делает именно то, что вы предложили. Спасибо 🙂

Ответ №1:

Очень просто. Сначала вам нужно объявить 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" amp; "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'])); 
}
 

Сделано! Вот так просто. Наслаждайтесь 🙂

Комментарии:

1. Работает как заклинание… Кроме того, плюс 1 за TODAY и YESTERDAY проверяет 🙂 Спасибо!