# How the PHPDTS Chat System Retrieves and Displays Messages Using getchat()

> Discover how the PHPDTS chat system retrieves and displays messages. Learn how the getchat() function queries the database, formats messages, and delivers them efficiently.

- Repository: [Nemo Ma/phpdts](https://github.com/amarillonmc/phpdts)
- Tags: how-to-guide
- Published: 2026-02-24

---

**The PHPDTS chat system relies on the `getchat()` function defined in [`include/global.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/global.func.php) to query the MySQL `chat` table for new messages, format them as HTML based on message type, and deliver them via JSON endpoints or direct template rendering.**

The PHPDTS (PHP Deathmatch Translation System) repository implements a lightweight chat subsystem that bridges database storage and real-time browser updates. Understanding how to retrieve and display messages in this open-source game engine requires examining the `getchat()` function, which serves as the central retrieval mechanism for all chat-related views. This implementation pattern supports both AJAX polling for live updates and server-side rendering for full page loads.

## How getchat() Retrieves Messages from the Database

The core retrieval logic resides in [`include/global.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/global.func.php) between lines 82 and 120. When invoked, `getchat()` accepts three parameters: `$last` (the last message ID the client knows), `$team` (the current player's team ID), and `$chatlimit` (maximum rows to return).

First, the function determines the fetch limit. If the caller does not supply a limit, the global `$chatlimit` value is used as the default.

Next, it executes a selective SQL query against the `chat` table:

```php
$result = $db->query(
    "SELECT * FROM {$tablepre}chat WHERE cid>'$last'
     AND (type!='1' OR (type='1' AND recv='$team'))
     ORDER BY cid desc LIMIT $limit"
);

```

This query implements privacy controls for **team-only chat** (`type = 1`). Messages marked as type 1 only appear in results when the current player belongs to the same `$team` as the recipient specified in the `recv` column. The descending order by `cid` ensures the newest messages appear first.

## Formatting and Sanitizing Chat Output

After retrieval, `getchat()` prepares a result container array containing `lastcid` (tracking the highest message ID processed) and an empty `msg` list. The function then iterates over each database row to construct HTML fragments.

### Location and Metadata Preparation

Some chat types reference map locations. According to the source at `global.func.php#L89-L92`, the function builds `$tplsinfo` by merging `$plsinfo` and `$hplsinfo` arrays so that place names display correctly in message contexts.

### Message Processing Pipeline

For each row, the function performs three critical transformations:

1. **Security sanitization** – Raw messages pass through `htmlspecialchars()` to prevent XSS attacks.
2. **Emoji replacement** – Tokens like `[emoji]` convert to `<img>` tags for graphical display as seen at `global.func.php#L96-L98`.
3. **Type-based formatting** – Different CSS classes apply based on the chat type (global, clan, system, death, etc.).

The HTML construction follows this pattern for normal global chat (type 0) at `global.func.php#L99-L114`:

```php
$msg = "【{$chatinfo[$chat['type']]}】{$chat['send']}：{$chat['msg']}"
       .date("(H:i:s)", $chat['time']).'<br>';

```

Other types receive specific styling classes such as `clan`, `lime`, `red`, or `yellow` to differentiate system announcements from player dialogue.

## Delivering Messages to the Frontend

The PHPDTS architecture supports multiple consumption patterns for chat data, enabling both real-time updates and static page rendering.

### AJAX Polling via chat.php

The [`chat.php`](https://github.com/amarillonmc/phpdts/blob/main/chat.php) script serves as the primary endpoint for live chat updates. It calls `getchat($lastcid, $teamID)` and encodes the result as JSON:

```php
$chatdata = getchat($lastcid, $teamID);
echo compatible_json_encode($chatdata);

```

Client-side JavaScript polls this endpoint every few seconds, injecting new HTML fragments into the chat panel and updating the `lastcid` cursor to avoid duplicates.

### Full Page Rendering in game.php

For initial page loads, [`game.php`](https://github.com/amarillonmc/phpdts/blob/main/game.php) fetches the complete chat history by passing `0` as the last CID:

```php
$chatdata = getchat(0, $teamID);
$emdata   = get_emdata();
include template('chat');

```

The `templates/nouveau/chat.htm` template receives the `$chatdata['msg']` array and iterates over it to print formatted messages directly into the HTML response.

### News Integration

The [`news.php`](https://github.com/amarillonmc/phpdts/blob/main/news.php) file demonstrates alternative usage by calling `getchat(0,'',$chatinnews)` to embed recent chat activity within news views, proving the function's flexibility across different contexts.

## Code Implementation Examples

### Inserting a Chat Message

When players submit messages, [`chat.php`](https://github.com/amarillonmc/phpdts/blob/main/chat.php) handles the database insertion:

```php
if ($sendmode == 'send' && $chatmsg) {
    $db->query(
        "INSERT INTO {$tablepre}chat (type,`time`,send,msg)
         VALUES ('0','$now','$cuser','$chatmsg')"
    );
}

```

### Client-Side Polling Implementation

The browser polls for updates using JavaScript:

```javascript
setInterval(function () {
    fetch('chat.php?lastcid=' + lastSeenCid)
        .then(r => r.json())
        .then(data => {
            Object.values(data.msg).forEach(html => 
                chatBox.insertAdjacentHTML('beforeend', html)
            );
            lastSeenCid = data.lastcid;
        });
}, 2000);

```

### Server-Side Template Rendering

The returned data structure follows this associative array format:

```php
[
  'lastcid' => 15420,
  'msg'     => [
      15418 => '【全体】Player1：Hello world!(14:32:01)<br>',
      15419 => '【队伍】Player2：Strategy?<br>',
      15420 => '<span class="red">【系统】Player3 has died.</span><br>'
  ]
]

```

## Summary

- **`getchat()`** in [`include/global.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/global.func.php) serves as the central retrieval function for all chat operations, querying the MySQL `chat` table with CID-based pagination.
- **Privacy filtering** occurs at the database level, ensuring team-only messages (`type = 1`) only reach authorized team members via the `$team` parameter.
- **Output formatting** combines `htmlspecialchars()` sanitization, emoji token replacement, and type-specific CSS classes to generate safe, styled HTML fragments.
- **Dual delivery modes** support both AJAX JSON responses through [`chat.php`](https://github.com/amarillonmc/phpdts/blob/main/chat.php) and server-side template rendering in [`game.php`](https://github.com/amarillonmc/phpdts/blob/main/game.php) and [`news.php`](https://github.com/amarillonmc/phpdts/blob/main/news.php).
- **Cursor-based pagination** using `lastcid` prevents duplicate message delivery during long polling cycles.

## Frequently Asked Questions

### How does getchat() filter team-only messages in PHPDTS?

The function applies SQL-level filtering in the WHERE clause: `AND (type!='1' OR (type='1' AND recv='$team'))`. This ensures rows with `type = 1` (team-only) only return when the current player's team ID matches the `recv` column value. Global messages (type 0) bypass this restriction and appear for all users.

### What data structure does getchat() return?

The function returns an associative array containing two keys: `lastcid` (an integer representing the highest message ID processed) and `msg` (an array mapping CID integers to HTML strings). This structure allows callers to track synchronization state while receiving ready-to-render message fragments.

### How are emojis rendered in the PHPDTS chat system?

During message iteration, `getchat()` applies a replacement function that transforms `[emoji]` tokens into `<img>` tags. This occurs after `htmlspecialchars()` sanitization but before HTML concatenation, ensuring emoji images render safely within the formatted output strings stored in `$chatdata['msg']`.

### Which files are responsible for displaying chat messages?

Three primary files handle display: [`chat.php`](https://github.com/amarillonmc/phpdts/blob/main/chat.php) (AJAX JSON endpoint for live updates), [`game.php`](https://github.com/amarillonmc/phpdts/blob/main/game.php) (full-page server-side rendering using `templates/nouveau/chat.htm`), and [`news.php`](https://github.com/amarillonmc/phpdts/blob/main/news.php) (embedding chat within news views). All three rely on `getchat()` defined in [`include/global.func.php`](https://github.com/amarillonmc/phpdts/blob/main/include/global.func.php) for message retrieval.