You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

技术问询:在JS中嵌套PHP,用xmlhttp、toastr实现MySQL消息全员推送

Hey Zac, let's break down how to refine your real-time message display setup with XMLHTTP, toastr, PHP, and MySQL—here's a step-by-step guide to make it more robust, secure, and user-friendly:

1. Fix & Optimize the Frontend Polling Logic

Your current fixed 5-second interval can lead to overlapping requests if a query takes longer than expected. Instead, trigger the next poll only after the previous request completes to avoid server overload. Also, avoid passing the username in the URL (it’s vulnerable to tampering)—let the backend pull it directly from the session.

Here's improved frontend code (using native XMLHTTP; we can also use jQuery for cleaner syntax):

function fetchNewMessages() {
  const xmlhttp = new XMLHttpRequest();
  
  xmlhttp.onreadystatechange = function() {
    if (this.readyState === 4) {
      if (this.status === 200) {
        try {
          const response = JSON.parse(this.responseText);
          
          // Show toastr for each new message
          if (response.messages.length > 0) {
            response.messages.forEach(msg => {
              $.toast({
                heading: msg.title,
                text: msg.message,
                position: 'top-right', // Customize position as needed
                showHideTransition: 'slide',
                icon: 'info', // Use 'error'/'success' for different message types
                hideAfter: 5000 // Auto-hide after 5 seconds
              });
            });
          }
        } catch (e) {
          console.error('Failed to parse response:', e);
        }
      } else {
        console.error('Request failed with status:', this.status);
      }
      // Schedule next poll only after this request finishes
      setTimeout(fetchNewMessages, 5000);
    }
  };

  xmlhttp.open("GET", "includes/ajax/user/general/messages.php", true);
  xmlhttp.send();
}

// Start the polling loop on page load
window.onload = fetchNewMessages;
2. Secure & Refine the PHP Backend

Your messages.php needs to handle SQL injection, mark messages as read to avoid duplicate popups, and return structured JSON. Here's a secure implementation:

<?php
session_start();

// Block unauthenticated users
if (!isset($_SESSION['username'])) {
  echo json_encode(['messages' => []]);
  exit;
}

$username = $_SESSION['username'];

// Connect to MySQL (use mysqli or PDO for prepared statements)
$conn = mysqli_connect("localhost", "your_db_user", "your_db_pass", "your_db_name");
if (!$conn) {
  error_log("Database connection failed: " . mysqli_connect_error());
  echo json_encode(['messages' => []]);
  exit;
}

// Fetch unread messages using prepared statements (prevents SQL injection)
$stmt = $conn->prepare("SELECT id, title, message FROM messages WHERE recipient = ? AND is_read = 0");
$stmt->bind_param("s", $username);
$stmt->execute();
$result = $stmt->get_result();

$messages = [];
while ($row = $result->fetch_assoc()) {
  $messages[] = $row;
  
  // Mark message as read to avoid re-showing it
  $updateStmt = $conn->prepare("UPDATE messages SET is_read = 1 WHERE id = ?");
  $updateStmt->bind_param("i", $row['id']);
  $updateStmt->execute();
  $updateStmt->close();
}

$stmt->close();
mysqli_close($conn);

// Return JSON response
header('Content-Type: application/json');
echo json_encode(['messages' => $messages]);
?>

Key notes here:

  • Use prepared statements to eliminate SQL injection risks.
  • Mark messages as is_read once fetched so users don't see duplicates.
  • Add error logging for debugging, and always return valid JSON even if something fails.
3. Toastr Best Practices

Make sure you've properly included toastr's dependencies first:

<!-- Include jQuery first -->
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<!-- Toastr CSS & JS -->
<link rel="stylesheet" href="path/to/toastr.css">
<script src="path/to/toastr.min.js"></script>

Customize toastr behavior to fit your needs:

  • Use different icon values (info, success, warning, error) to match message types.
  • Adjust hideAfter to control how long popups stay visible (set to false to keep them until manually closed).
  • Use position to place popups where they won't block important content (e.g., top-center, bottom-right).
4. Long-Term Improvements

If you expect a lot of users, short polling (every 5 seconds) can strain your server. Consider these upgrades:

  • Long Polling (Comet): Keep the HTTP connection open until new messages are available, then immediately re-establish it. This reduces unnecessary requests.
  • WebSocket: Use a library like Ratchet for PHP to implement real-time, bidirectional communication. The server pushes messages to clients instantly, no polling needed.
  • Frontend Message Caching: Store IDs of displayed messages in localStorage as an extra layer of protection against duplicates.

内容的提问来源于stack exchange,提问作者Zac Ram

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:48:23