Короткий ответ: учебный PHP-чат можно сделать из одного файла index.php и файла messages.json: форма отправляет имя и сообщение, PHP сохраняет их, затем страница выводит последние сообщения
Это не production-чат и не замена Telegram. Такой пример нужен, чтобы понять механику: форма, POST-запрос, хранение данных, вывод HTML и базовая защита от пользовательского ввода. Когда эта логика станет понятной, можно переходить к базе данных, авторизации и обновлению сообщений без перезагрузки
Структура проекта
Создайте папку
mkdir php-chat
cd php-chat
Внутри будут два файла
php-chat/
index.php
messages.json
Создайте пустой messages.json
[]
Код простого чата
Файл index.php
<?php
$messagesFile = __DIR__ . '/messages.json';
if (!file_exists($messagesFile)) {
file_put_contents($messagesFile, '[]');
}
$messages = json_decode(file_get_contents($messagesFile), true);
if (!is_array($messages)) {
$messages = [];
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$text = trim($_POST['text'] ?? '');
if ($name !== '' && $text !== '') {
$messages[] = [
'name' => $name,
'text' => $text,
'created_at' => date('Y-m-d H:i:s')
];
$messages = array_slice($messages, -50);
file_put_contents(
$messagesFile,
json_encode($messages, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
);
header('Location: /');
exit;
}
}
?>
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<title>PHP-чат</title>
<style>
body { font-family: Arial, sans-serif; max-width: 720px; margin: 40px auto; }
form { display: grid; gap: 12px; margin-bottom: 24px; }
input, textarea, button { font: inherit; padding: 10px; }
.message { border-bottom: 1px solid #ddd; padding: 12px 0; }
.date { color: #777; font-size: 14px; }
</style>
</head>
<body>
<h1>PHP-чат своими руками</h1>
<form method="post">
<input name="name" placeholder="Ваше имя">
<textarea name="text" placeholder="Сообщение"></textarea>
<button type="submit">Отправить</button>
</form>
<h2>Сообщения</h2>
<?php foreach (array_reverse($messages) as $message): ?>
<div class="message">
<strong><?php echo htmlspecialchars($message['name']); ?></strong>
<div class="date"><?php echo htmlspecialchars($message['created_at']); ?></div>
<p><?php echo nl2br(htmlspecialchars($message['text'])); ?></p>
</div>
<?php endforeach; ?>
</body>
</html>
Запуск
В папке проекта выполните
php -S localhost:8000
Откройте
http://localhost:8000
Введите имя, сообщение и отправьте форму. Если сообщение появилось в ленте, чат работает
Что делает код
Файл messages.json хранит сообщения в виде массива. Когда пользователь отправляет форму, PHP берет name и text из $_POST, добавляет дату, записывает массив обратно в JSON и делает редирект на главную страницу
Редирект после POST нужен, чтобы при обновлении страницы браузер не отправлял форму повторно. Это простой прием, который часто называют Post/Redirect/Get
htmlspecialchars() защищает страницу от ситуации, когда пользователь вводит HTML или JavaScript вместо обычного текста. Без этого учебный чат быстро превращается в демонстрацию XSS-ошибки
Почему файл подходит только для учебного проекта
Хранить сообщения в JSON удобно для первого примера, но плохо для реального чата. При одновременной записи несколькими пользователями файл может конфликтовать. Для настоящего проекта лучше использовать базу данных: MySQL, PostgreSQL или SQLite
Также здесь нет авторизации, защиты от спама, CSRF-токена, ограничений частоты отправки и модерации. Это нормально для учебного примера, но не для публичного сайта
Мини-практика
Добавьте проверку длины сообщения: если текст длиннее 500 символов, не сохраняйте его и покажите ошибку над формой. Затем добавьте поле room и попробуйте выводить сообщения только одной комнаты
Так вы приблизитесь к настоящему чату, но не потеряете простую структуру проекта
Частые ошибки
Файл messages.json не записывается Проверьте права на папку проекта. PHP должен иметь право создавать и изменять файл
Сообщение повторяется после обновления страницы После успешной записи используйте header('Location: /') и exit
Пользовательский HTML отображается как код страницы Выводите имя и текст через htmlspecialchars()
Пытаются сделать real-time без базы и WebSocket Сначала соберите обычный чат с сохранением, затем думайте про автообновление, AJAX или WebSocket
Что почитать дальше по PHP
Если нужен общий маршрут по теме, откройте рубрику PHP. Для соседних задач пригодятся эти разборы:
- Composer в PHP: установка пакетов без ручного копирования
- PHP и MySQL через PDO: первая база без SQL-инъекций
- Telegram-бот на PHP: простой бот через Bot API
- Как обновить PHP на WordPress без поломки сайта



