
Создание функционала добавления друзей в PHP требует корректной организации базы данных и управления связями между пользователями. Наиболее распространённая схема предполагает таблицу users с уникальным идентификатором пользователя и отдельную таблицу friends, где хранится информация о подтверждённых и ожидающих запросах на дружбу.
Первый шаг – реализовать обработку запросов на добавление. Рекомендуется использовать подготовленные выражения PDO для защиты от SQL-инъекций. Каждое нажатие кнопки «Добавить друга» должно создавать запись с id_отправителя, id_получателя и статусом запроса, например, ‘pending’.
Далее необходимо реализовать подтверждение и отклонение запросов. Для этого создаются функции, которые обновляют статус запроса на ‘accepted’ или удаляют запись при отклонении. Важно проверять наличие существующих запросов, чтобы избежать дублирования и некорректных связей между пользователями.
Добавление друзей в PHP: пошаговое руководство

Для реализации функционала добавления друзей в PHP необходимо подготовить базу данных, создать формы для отправки запросов и написать серверную логику для обработки этих запросов.
1. Структура базы данных

Создайте таблицу для хранения информации о друзьях:
CREATE TABLE friends (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
friend_id INT NOT NULL,
status ENUM('pending','accepted') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_friend (user_id, friend_id)
);
Обязательно добавьте индексы для ускорения выборок по user_id и friend_id.
2. Форма отправки запроса на добавление

Простейшая HTML-форма для добавления друга:
<form method="POST" action="add_friend.php">
<input type="number" name="friend_id" placeholder="ID друга" required>
<button type="submit">Добавить друга</button>
</form>
3. Обработка запроса на сервере
Создайте файл add_friend.php с проверкой данных и добавлением записи в базу:
- Подключение к базе данных через PDO или MySQLi.
- Проверка, что пользователь не добавляет самого себя:
- Проверка существования уже существующей записи:
- Добавление новой записи с статусом
pending:
if ($user_id == $_POST['friend_id']) {
die('Нельзя добавить себя.');
}
$stmt = $pdo->prepare('SELECT * FROM friends WHERE user_id = ? AND friend_id = ?');
$stmt->execute([$user_id, $_POST['friend_id']]);
if ($stmt->rowCount() > 0) {
die('Запрос уже отправлен или пользователь уже в друзьях.');
}
$stmt = $pdo->prepare('INSERT INTO friends (user_id, friend_id) VALUES (?, ?)');
$stmt->execute([$user_id, $_POST['friend_id']]);
4. Принятие запроса
Для принятия запроса создайте обработчик, который изменяет статус на accepted:
$stmt = $pdo->prepare('UPDATE friends SET status = "accepted" WHERE id = ? AND friend_id = ?');
$stmt->execute([$request_id, $user_id]);
Чтобы получить список всех друзей пользователя:
$stmt = $pdo->prepare('
SELECT u.id, u.name
FROM users u
JOIN friends f ON (u.id = f.friend_id OR u.id = f.user_id)
WHERE (f.user_id = ? OR f.friend_id = ?) AND f.status = "accepted"
');
$stmt->execute([$user_id, $user_id]);
$friends = $stmt->fetchAll();
Создание таблицы для хранения друзей в базе данных
Для хранения информации о друзьях в MySQL создайте таблицу с четкой структурой. Минимальный набор полей включает id, user_id, friend_id и added_at. Поле id должно быть PRIMARY KEY с автоинкрементом. Поля user_id и friend_id – INT UNSIGNED, индексированные для ускорения поиска. Поле added_at хранит дату добавления друга, тип DATETIME с автоматической установкой текущего времени.
Пример SQL-запроса для создания таблицы:
CREATE TABLE friends (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_id INT UNSIGNED NOT NULL,
friend_id INT UNSIGNED NOT NULL,
added_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY unique_friendship (user_id, friend_id),
INDEX idx_user_id (user_id),
INDEX idx_friend_id (friend_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Уникальный ключ unique_friendship предотвращает дублирование связей. Индексы idx_user_id и idx_friend_id ускоряют выборку друзей конкретного пользователя и поиск обратных связей. Для хранения больших объемов данных рекомендуется использовать InnoDB с кодировкой utf8mb4 для поддержки всех символов.
Для связки с таблицей пользователей user_id и friend_id можно добавить FOREIGN KEY, чтобы обеспечивать целостность данных:
ALTER TABLE friends
ADD CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
ADD CONSTRAINT fk_friend FOREIGN KEY (friend_id) REFERENCES users(id) ON DELETE CASCADE;
Эта структура позволяет быстро получать список друзей, добавлять новые связи и контролировать целостность данных без лишних проверок на уровне PHP.
Настройка соединения с базой данных в PHP

Для работы с друзьями в приложении необходимо настроить соединение с базой данных MySQL или MariaDB. Рекомендуется использовать расширение mysqli или PDO для безопасного взаимодействия с базой.
Пример настройки через mysqli:
<?php
$host = 'localhost';
$user = 'имя_пользователя';
$password = 'пароль';
$database = 'имя_базы';
$connection = new mysqli($host, $user, $password, $database);
if ($connection->connect_error) {
die('Ошибка подключения: ' . $connection->connect_error);
}
?>
Для PDO конфигурация выглядит следующим образом:
<?php
$dsn = 'mysql:host=localhost;dbname=имя_базы;charset=utf8';
$user = 'имя_пользователя';
$password = 'пароль';
try {
$pdo = new PDO($dsn, $user, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die('Ошибка подключения: ' . $e->getMessage());
}
?>
Рекомендации:
| Параметр | Описание |
|---|---|
| $host | Адрес сервера базы данных, чаще всего localhost. |
| $user | Имя пользователя с правами на чтение и запись в базе. |
| $password | Пароль пользователя. Для безопасности храните в отдельном файле вне корня сайта. |
| $database | Название базы, в которой будут храниться данные о друзьях. |
| PDO::ATTR_ERRMODE | Режим обработки ошибок, рекомендуется использовать PDO::ERRMODE_EXCEPTION для отладки и логирования. |
После настройки соединения можно переходить к созданию таблицы друзей и реализации функций добавления и отображения контактов.
Форма для отправки запроса на добавление друга

Для создания формы используйте тег <form> с методом POST и указанием обработчика на сервере, например add_friend.php. В форме обязательно включите поле для ввода идентификатора пользователя или его имени:
<input type="text" name="friend_username" required maxlength="50"> – атрибут required предотвращает отправку пустого значения, maxlength ограничивает длину строки, что снижает риск ошибок и SQL-инъекций.
Добавьте кнопку отправки запроса:
<button type="submit">Добавить друга</button> – она инициирует передачу данных на сервер.
Для безопасности используйте скрытое поле с токеном CSRF:
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>"> – это предотвращает внешние поддельные запросы.
Поле для комментария к запросу необязательно, но позволяет пользователю добавить пояснение. Его можно реализовать так:
<textarea name="message" maxlength="200"></textarea> – ограничение длины предотвращает чрезмерно длинные сообщения.
После отправки формы на сервере следует проверить наличие пользователя, проверить токен CSRF и убедиться, что пользователь еще не добавлен в друзья, прежде чем сохранять запись в базе данных.
Пример полной формы:
<form action="add_friend.php" method="POST">
<input type="text" name="friend_username" required maxlength="50" placeholder="Имя пользователя">
<textarea name="message" maxlength="200" placeholder="Комментарий"></textarea>
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['csrf_token']; ?>">
<button type="submit">Добавить друга</button>
</form>
Обработка данных формы и проверка существующих друзей
Для начала необходимо получить данные, отправленные пользователем через форму. Используйте метод POST, чтобы избежать передачи данных в URL:
$friend_email = trim($_POST['friend_email']);
Обязательно проверяйте формат email перед обработкой:
if (!filter_var($friend_email, FILTER_VALIDATE_EMAIL)) {
echo "Неверный формат email";
exit;
}
Следующий шаг – проверка, существует ли пользователь с таким email в базе данных:
$stmt = $pdo->prepare("SELECT id FROM users WHERE email = :email");
$stmt->execute(['email' => $friend_email]);
$user = $stmt->fetch();
if (!$user) {
echo "Пользователь не найден";
exit;
}
После подтверждения существования пользователя проверяем, не является ли он уже другом текущего пользователя:
$stmt = $pdo->prepare("SELECT id FROM friends WHERE user_id = :user_id AND friend_id = :friend_id");
$stmt->execute(['user_id' => $current_user_id, 'friend_id' => $user['id']]);
$existing_friend = $stmt->fetch();
if ($existing_friend) {
echo "Этот пользователь уже в списке друзей";
exit;
}
Если проверка пройдена, можно добавить запись о новом друге в таблицу:
$stmt = $pdo->prepare("INSERT INTO friends (user_id, friend_id, created_at) VALUES (:user_id, :friend_id, NOW())");
$stmt->execute(['user_id' => $current_user_id, 'friend_id' => $user['id']]);
Для визуализации текущих друзей используйте таблицу:
| ID | Дата добавления | |
|---|---|---|
| {$row[‘id’]} | {$row[’email’]} | {$row[‘created_at’]} |
Сохранение нового друга в базе данных
После получения данных нового друга из формы необходимо корректно сохранить их в базе данных. В PHP чаще используют MySQL или PostgreSQL. Ниже представлены конкретные шаги и рекомендации.
- Создание подключения к базе данных:
Используйте объект PDO для безопасного подключения и работы с базой.
$dsn = 'mysql:host=localhost;dbname=friendlist;charset=utf8'; $user = 'username'; $pass = 'password'; $options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]; $pdo = new PDO($dsn, $user, $pass, $options); - Подготовка SQL-запроса:
Используйте подготовленные выражения для предотвращения SQL-инъекций.
$stmt = $pdo->prepare('INSERT INTO friends (name, email, phone) VALUES (:name, :email, :phone)'); - Привязка данных и выполнение запроса:
Присвойте значения из формы и выполните запрос.
$stmt->bindParam(':name', $_POST['name']); $stmt->bindParam(':email', $_POST['email']); $stmt->bindParam(':phone', $_POST['phone']); $stmt->execute(); - Проверка успешного добавления:
Проверяйте возвращаемое значение execute() или используйте rowCount() для подтверждения.
if($stmt->rowCount() > 0){ echo 'Друг успешно добавлен'; } else { echo 'Ошибка при добавлении'; } - Рекомендации по безопасности и структуре:
- Проверяйте формат e-mail через filter_var($_POST[’email’], FILTER_VALIDATE_EMAIL).
- Для больших таблиц используйте индексы по e-mail и phone для ускорения поиска.
Следуя этим шагам, новые друзья будут добавляться корректно и безопасно, а структура базы останется оптимальной для дальнейшей работы.
Для отображения списка друзей в PHP необходимо выполнить несколько конкретных шагов: получить данные из базы, обработать их и корректно вывести на страницу. Ниже приведён пример последовательности действий.
- Создайте SQL-запрос для выборки друзей текущего пользователя. Предположим, есть таблица
friendsс колонкамиuser_idиfriend_id:
$userId = $_SESSION['user_id'];
$sql = "SELECT u.id, u.username, u.email FROM users u
INNER JOIN friends f ON u.id = f.friend_id
WHERE f.user_id = ?";
- Используйте подготовленные выражения для защиты от SQL-инъекций:
$stmt = $pdo->prepare($sql);
$stmt->execute([$userId]);
$friends = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($friends) === 0) {
echo "<p>У вас пока нет друзей.</p>";
} else {
echo "<ul>";
foreach ($friends as $friend) {
echo "<li>" . htmlspecialchars($friend['username']) . " (" . htmlspecialchars($friend['email']) . ")</li>";
}
echo "</ul>";
Дополнительно можно добавить ссылки для отправки сообщений или удаления друга, например:
<a href='message.php?to={$friend['id']}'>Написать сообщение</a><a href='remove_friend.php?id={$friend['id']}'>Удалить из друзей</a>
Удаление друга из списка с помощью PHP

Для удаления друга необходимо иметь уникальный идентификатор пользователя, которого вы хотите удалить. Обычно это user_id или friend_id в базе данных.
Простейший способ – использовать SQL-запрос с условием WHERE, чтобы удалить запись из таблицы связей между пользователями:
Пример запроса:
DELETE FROM friends WHERE user_id = :user_id AND friend_id = :friend_id
В PHP это реализуется через подготовленные выражения PDO, чтобы исключить возможность SQL-инъекций:
$stmt = $pdo->prepare('DELETE FROM friends WHERE user_id = :user_id AND friend_id = :friend_id');
$stmt->execute(['user_id' => $currentUserId, 'friend_id' => $friendId]);
После выполнения запроса важно проверить результат. Метод rowCount() возвращает количество удалённых записей. Если значение равно 0, значит связь не существовала или идентификаторы указаны неверно:
if ($stmt->rowCount() > 0) { echo 'Друг удалён'; } else { echo 'Друг не найден'; }
Для интерфейса лучше использовать POST-запрос с CSRF-токеном, чтобы защитить операцию удаления от внешних атак. Перед удалением рекомендуется проверять, что currentUserId соответствует текущей сессии пользователя.
Если структура базы данных содержит дополнительные зависимости, например таблицу сообщений или общего контента, необходимо одновременно удалить или обновить соответствующие записи, чтобы избежать нарушений ссылочной целостности.
Добавление уведомлений о новых запросах на дружбу

Для реализации уведомлений необходимо создать отдельную таблицу в базе данных, например `friend_requests_notifications`, с полями: `id` (INT, автоинкремент), `user_id` (INT, получатель запроса), `sender_id` (INT, отправитель запроса), `status` (ENUM(‘new’,’seen’)), `created_at` (TIMESTAMP). Это позволит отслеживать новые и просмотренные запросы.
При отправке запроса на дружбу вставляйте запись в таблицу уведомлений с `status = ‘new’`. Пример SQL-запроса:
INSERT INTO friend_requests_notifications (user_id, sender_id, status, created_at) VALUES (?, ?, 'new', NOW())
Для отображения уведомлений создайте метод, который извлекает все записи с `status = ‘new’` для конкретного пользователя. В PHP это можно сделать через подготовленный запрос с `PDO`:
$stmt = $pdo->prepare("SELECT * FROM friend_requests_notifications WHERE user_id = ? AND status = 'new'");
$stmt->execute([$currentUserId]);
$notifications = $stmt->fetchAll();
После просмотра уведомления рекомендуется обновлять статус на `seen`, чтобы исключить повторное отображение:
$update = $pdo->prepare("UPDATE friend_requests_notifications SET status = 'seen' WHERE id = ?");
$update->execute([$notificationId]);
Для мгновенных уведомлений используйте AJAX-запросы с интервалом опроса сервера. Пример JavaScript запроса к PHP-скрипту:
setInterval(() => {
fetch('check_notifications.php')
.then(response => response.json())
.then(data => {
if(data.length > 0) showNotification(data);
});
}, 5000);
Метод `showNotification(data)` может добавлять новые уведомления в DOM. Для производительности рекомендуется извлекать только последние 5–10 уведомлений и хранить ID уже отображённых, чтобы не перегружать интерфейс.
Вопрос-ответ:
Как организовать хранение списка друзей в базе данных для PHP-приложения?
Список друзей обычно хранится в отдельной таблице, где каждая запись содержит идентификаторы двух пользователей, которые являются друзьями. Часто добавляют поле для статуса запроса (например, «ожидание», «подтверждено») и дату добавления. Такая структура позволяет быстро проверять существующие связи и фильтровать запросы по статусу.
Какие меры безопасности нужно учитывать при отправке запроса на добавление друга?
Важно проверять, что пользователь авторизован, и защищать формы от CSRF-атак. Запросы должны валидировать идентификаторы пользователей, чтобы исключить возможность подставить чужой ID. Также полезно ограничивать частоту отправки запросов, чтобы предотвратить спам и злоупотребления.
Можно ли реализовать функцию добавления друзей без использования JavaScript?
Да, такую функцию можно сделать с помощью обычных форм и POST-запросов в PHP. Пользователь отправляет форму с ID друга, сервер проверяет данные, создает запись в базе и возвращает страницу с подтверждением. Однако интерфейс будет менее интерактивным по сравнению с использованием AJAX, так как страница будет перезагружаться после каждого запроса.
Как правильно отображать список друзей на странице профиля?
Сначала нужно получить все записи, где текущий пользователь указан как участник дружбы, и соединить их с таблицей пользователей для получения имен и аватаров. Для удобства можно использовать пагинацию или подгрузку по частям, чтобы страница не перегружалась при большом количестве друзей. Также можно отображать статус дружбы для каждого пользователя.
Что делать, если два пользователя отправили друг другу запросы одновременно?
При добавлении нового запроса стоит проверять, существует ли уже обратная заявка. Если такая запись есть, можно сразу менять статус на «подтверждено», не создавая дубликат. Это позволяет избежать конфликтов и лишних записей, а также упрощает логику отображения друзей для пользователей.
