2016-11-24 3 views
0

У меня есть система обмена сообщениями (PHP/MySQL), и я уже подготовил поле для чтения/непрочитанные в простой таблице сообщенийPhp эффективно помечать сообщения как прочитанные

Table 
- msgbody 
- datetime 
- receipent 
- read/unread 
- sent/unsent (this field is for sending of notification) 

У меня есть 2 вопроса

  1. Я понимаю, что когда пользователь создаст сообщение, я вставлю в таблицу с полем «Непрочитано», и когда я впервые получаю сообщение со следующим сообщением

    MYSQL statement: Select * from table WHERE receipient = "a"; 
    

Что я делаю, я иду через массив, а затем я установил непрочитанное поле для чтения с помощью нескольких операторов вставки (очень неэффективно!)

Есть в любом случае я могу отказаться от цикла массива и обновить поле когда я его выбираю?

И это правильный способ определить, прочитано ли сообщение?

2) Я использую jquery как мой интерфейс, и я могу сделать ajax-вызов php, но мне все же интересно, как мне это сделать. Я определяю на переднем конце, загружен ли пользователь и видел сообщение или не.

Любой может пролить свет на то, как это сделать?

  • Ajax вызов для обновления, чтобы читать, когда вызов Ajax для загрузки является успешным?
  • Ajax вызов для обновления при чтении базы данных?
  • Ajax звонок для уточнения ...... когда?

ОБНОВЛЕНИЕ: Добавлены коды. Мой PHP код для вставки в сообщения

Отказ от ответственности: Коды работают нормально. это процесс, в котором мне нужна помощь.

$query = $this->db->prepare('INSERT INTO table (msgbody,date time,recipient,read,sent) VALUES(:msg,:date,:user,:read,:sent); 
if ($query->execute(array(
':msg' => $msg, 
':date' => $datetime, 
':user' => $user, 
':read' => '0', 
':sent' => '0'))) { 
return TRUE; 
} 


My php code for retrieving of message 

$query = $this->db->prepare('SELECT * FROM table WHERE recipient = :user); 
if ($query->execute(array(
':user' => $user 
))){ 

$data = $query->fetchAll(); 

foreach ($data as $msg) { 
if $msg['read'] == '0'; 
$this->updateRead($msg['id']); 


} 

$ this-> updateRead функция включает в себя обновление таблицы чтения поля к 1, а также отправка Pusher к первоначальному получателю, так что они знают, что сообщение читается.

Итак, что произойдет, если у меня есть 1000 сообщений, я могу закончить цикл 1000 раз, чтобы отметить 2-3 сообщения как Чтение.

+0

Ваша структура таблицы выглядит не очень хорошо. – Phiter

+0

Нет, нельзя комбинировать 'SELECT' с' UPDATE' в одном запросе. – Barmar

+0

Но звучит как идеальная ситуация для Подготовки один раз и выполнение многих – RiggsFolly

ответ

0

Вы не можете выполнить выбор и обновление в одном запросе. Но вам не нужен цикл, вы можете обновить все сообщения одним запросом.

START TRANSACTION; 
SELECT * FROM table WHERE recipient = 'a'; 
UPDATE table SET read = 1 WHERE recipient = 'a'; 
COMMIT; 

Если вы делаете это в транзакции, вам не нужно беспокоиться о добавлении новых сообщений между двумя запросами. Атомарность транзакций должна гарантировать, что они видят одинаковый вид базы данных.

+0

Я пробовал это, но я столкнулся с проблемой, когда сообщения отправляются слишком быстро, поэтому обновление и вставка заканчиваются обновлением вставленных сообщений. Я не понимаю, что вы подразумеваете под атомарностью транзакций. Поэтому я думаю, что я должен установить его как «Чтение», поскольку я его извлекаю. Но не другие данные, которые я не получил в тот момент. –

+0

Атомарность транзакций означает, что когда вы выполняете запросы внутри транзакции, изменения в базе данных, сделанные другими процессами, вам не видны. – Barmar

+0

OH Да, кстати, я также помнил, почему это не работает, потому что мне также нужно отправить сообщение первоначальному отправителю и обновить свой интерфейс с помощью состояния READ. –