如何在WHMCS中新建文件实现按ID/时间调取单个工单回复
Hey there! Let's break down how to build this feature step by step—we'll create a history.php file that pulls ticket replies from your database and supports fetching a single reply via lastreply (either reply ID or timestamp).
1. 参数接收与基础校验
First, we'll grab the URL parameters and do basic checks to block invalid requests:
// Get parameters from URL, with fallback defaults $tid = $_GET['tid'] ?? null; $c = $_GET['c'] ?? null; $lastreply = $_GET['lastreply'] ?? null; // Check for missing required parameters if (empty($tid) || empty($c) || empty($lastreply)) { die("Missing required parameters. Please check your request URL."); } // Validate ticket ID format (assuming it's numeric) if (!is_numeric($tid)) { die("Invalid ticket ID format."); }
2. Verify Access Permissions (for the c parameter)
The c parameter is likely a verification code to ensure the user has permission to access the ticket. Let's validate it against your database:
// Use PDO for database connections (safer than raw queries) $db = new PDO('mysql:host=localhost;dbname=your_database;charset=utf8', 'db_user', 'db_password'); // Check if the verification code matches the ticket $verifyStmt = $db->prepare("SELECT id FROM tickets WHERE id = ? AND verify_code = ?"); $verifyStmt->execute([$tid, $c]); $hasAccess = $verifyStmt->rowCount() > 0; if (!$hasAccess) { die("You don't have permission to access this ticket, or parameters are invalid."); }
3. Fetch the Target Reply Using lastreply
We need to handle two cases for lastreply: it could be a numeric reply ID, or a timestamp (like Unix time or Y-m-d H:i:s format). Here's how to build the query dynamically:
// Base query to target replies for the ticket $query = "SELECT reply_id, reply_content, reply_time FROM ticket_replies WHERE ticket_id = ?"; $params = [$tid]; // Determine if lastreply is an ID or timestamp if (is_numeric($lastreply)) { // Match by reply ID $query .= " AND reply_id = ?"; $params[] = $lastreply; } else { // Match by reply time (adjust format to match your database's time storage) $query .= " AND reply_time = ?"; $params[] = $lastreply; } // Execute the query $stmt = $db->prepare($query); $stmt->execute($params); $reply = $stmt->fetch(PDO::FETCH_ASSOC);
4. Output the Reply Content
Finally, display the reply (or a message if no match was found):
if ($reply) { echo "<div class='ticket-reply'>"; echo "<h4>Reply ID: {$reply['reply_id']}</h4>"; echo "<p>Posted on: " . date('Y-m-d H:i:s', strtotime($reply['reply_time'])) . "</p>"; // Escape content to prevent XSS attacks echo "<div class='reply-text'>" . htmlspecialchars($reply['reply_content']) . "</div>"; echo "</div>"; } else { echo "No matching reply found. Please check your `lastreply` parameter."; }
Critical Security Notes
- Always use prepared statements: This prevents SQL injection attacks—never concatenate raw user input into your SQL queries.
- Escape output: Using
htmlspecialchars()on user-generated content stops cross-site scripting (XSS) attacks. - Restrict access: The
cparameter validation ensures only authorized users can view ticket replies, so don't skip this step!
内容的提问来源于stack exchange,提问作者Medhat

