New chat
Today
js генерация пазлов svg внутри к
dynamic sidebar html css bootstr
Yesterday
использовать bootstrap jquery da
1 обработать форму ajax <form me
php imap
используя php bootstrap datatabl
fullcalendar datatable
php прибывать к формату 2025-02-
7 Days
код js
кто я
code pj
Get App
My Profile
код js
код защита формы на js и php от спама и ботов во время отправки ajax
2 / 2

Для защиты формы от спама и ботов при отправке через AJAX на JavaScript и PHP, можно использовать несколько методов. Вот пример реализации:

1. Капча (например, Google reCAPTCHA)

Использование капчи — это один из самых надежных способов защиты от ботов.

На стороне клиента (HTML + JavaScript):

html
Copy
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Форма с защитой от ботов</title>
    <script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
    <form id="myForm">
        <input type="text" name="name" placeholder="Ваше имя" required>
        <input type="email" name="email" placeholder="Ваш email" required>
        <div class="g-recaptcha" data-sitekey="ВАШ_SITE_KEY"></div>
        <button type="submit">Отправить</button>
    </form>

    <script>
        document.getElementById('myForm').addEventListener('submit', function(event) {
            event.preventDefault();

            const formData = new FormData(this);
            const captchaResponse = grecaptcha.getResponse();

            if (!captchaResponse) {
                alert('Пожалуйста, подтвердите, что вы не робот.');
                return;
            }

            formData.append('g-recaptcha-response', captchaResponse);

            fetch('submit.php', {
                method: 'POST',
                body: formData
            })
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    alert('Форма успешно отправлена!');
                } else {
                    alert('Ошибка: ' + data.message);
                }
            })
            .catch(error => {
                console.error('Ошибка:', error);
            });
        });
    </script>
</body>
</html>

На стороне сервера (PHP):

php
Copy
<?php
$secretKey = "ВАШ_SECRET_KEY";
$captcha = $_POST['g-recaptcha-response'];

if (!$captcha) {
    echo json_encode(['success' => false, 'message' => 'Капча не была отправлена.']);
    exit;
}

$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=$secretKey&response=$captcha");
$responseKeys = json_decode($response, true);

if (intval($responseKeys["success"]) !== 1) {
    echo json_encode(['success' => false, 'message' => 'Ошибка проверки капчи.']);
    exit;
}

// Обработка данных формы
$name = $_POST['name'];
$email = $_POST['email'];

// Здесь можно добавить код для сохранения данных в базу данных или отправки email

echo json_encode(['success' => true, 'message' => 'Данные успешно обработаны.']);
?>

2. Скрытое поле (Honeypot)

Добавьте скрытое поле в форму, которое будет заполняться только ботами. Если это поле заполнено, форма не будет обработана.

На стороне клиента (HTML + JavaScript):

html
Copy
<form id="myForm">
    <input type="text" name="name" placeholder="Ваше имя" required>
    <input type="email" name="email" placeholder="Ваш email" required>
    <input type="text" name="honeypot" style="display:none;">
    <button type="submit">Отправить</button>
</form>

<script>
    document.getElementById('myForm').addEventListener('submit', function(event) {
        event.preventDefault();

        const formData = new FormData(this);

        if (formData.get('honeypot')) {
            alert('Обнаружен бот!');
            return;
        }

        fetch('submit.php', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                alert('Форма успешно отправлена!');
            } else {
                alert('Ошибка: ' + data.message);
            }
        })
        .catch(error => {
            console.error('Ошибка:', error);
        });
    });
</script>

На стороне сервера (PHP):

php
Copy
<?php
if (!empty($_POST['honeypot'])) {
    echo json_encode(['success' => false, 'message' => 'Обнаружен бот!']);
    exit;
}

// Обработка данных формы
$name = $_POST['name'];
$email = $_POST['email'];

// Здесь можно добавить код для сохранения данных в базу данных или отправки email

echo json_encode(['success' => true, 'message' => 'Данные успешно обработаны.']);
?>

3. Токен CSRF

Использование CSRF-токена для защиты от межсайтовой подделки запросов.

На стороне клиента (HTML + JavaScript):

html
Copy
<form id="myForm">
    <input type="text" name="name" placeholder="Ваше имя" required>
    <input type="email" name="email" placeholder="Ваш email" required>
    <input type="hidden" name="csrf_token" value="СГЕНЕРИРОВАННЫЙ_ТОКЕН">
    <button type="submit">Отправить</button>
</form>

<script>
    document.getElementById('myForm').addEventListener('submit', function(event) {
        event.preventDefault();

        const formData = new FormData(this);

        fetch('submit.php', {
            method: 'POST',
            body: formData
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                alert('Форма успешно отправлена!');
            } else {
                alert('Ошибка: ' + data.message);
            }
        })
        .catch(error => {
            console.error('Ошибка:', error);
        });
    });
</script>

На стороне сервера (PHP):

php
Copy
<?php
session_start();

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token']) {
        echo json_encode(['success' => false, 'message' => 'Неверный CSRF-токен.']);
        exit;
    }

    // Обработка данных формы
    $name = $_POST['name'];
    $email = $_POST['email'];

    // Здесь можно добавить код для сохранения данных в базу данных или отправки email

    echo json_encode(['success' => true, 'message' => 'Данные успешно обработаны.']);
} else {
    // Генерация CSRF-токена
    $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
?>

4. Ограничение частоты отправки

Можно ограничить количество отправок формы с одного IP-адреса за определенный промежуток времени.

На стороне сервера (PHP):

php
Copy
<?php
session_start();

$ip = $_SERVER['REMOTE_ADDR'];
$currentTime = time();
$timeLimit = 60; // 1 минута
$maxRequests = 3;

if (!isset($_SESSION['requests'])) {
    $_SESSION['requests'] = [];
}

$_SESSION['requests'] = array_filter($_SESSION['requests'], function($time) use ($currentTime, $timeLimit) {
    return $time > $currentTime - $timeLimit;
});

if (count($_SESSION['requests']) >= $maxRequests) {
    echo json_encode(['success' => false, 'message' => 'Слишком много запросов. Попробуйте позже.']);
    exit;
}

$_SESSION['requests'][] = $currentTime;

// Обработка данных формы
$name = $_POST['name'];
$email = $_POST['email'];

// Здесь можно добавить код для сохранения данных в базу данных или отправки email

echo json_encode(['success' => true, 'message' => 'Данные успешно обработаны.']);
?>

Заключение

Комбинируя эти методы, можно значительно повысить защиту формы от спама и ботов. Например, можно использовать капчу вместе с CSRF-токеном и ограничением частоты отправки.

7 / 7
использовать php bootstrap jquery fullcalendar js 1 подключить fullcalendar создания события в календаре по выделением датам или по клику создать или редактировать событие даты и время и заголовка с описанием 2 отправить данную форму ajax методом post и обработать форму в php

Для реализации функционала создания и редактирования событий в календаре с использованием FullCalendar, jQuery, Bootstrap и PHP, а также отправки данных через AJAX, выполним следующие шаги:


1. Подключение необходимых библиотек

Включим необходимые библиотеки в HTML-файл:

html
Copy
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FullCalendar Example</title>
    <!-- Bootstrap CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <!-- FullCalendar CSS -->
    <link href="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
        <div id="calendar"></div>
    </div>

    <!-- Modal для создания/редактирования события -->
    <div class="modal fade" id="eventModal" tabindex="-1" aria-labelledby="eventModalLabel" aria-hidden="true">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="eventModalLabel">Создать событие</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <form id="eventForm">
                        <input type="hidden" id="eventId">
                        <div class="mb-3">
                            <label for="eventTitle" class="form-label">Заголовок</label>
                            <input type="text" class="form-control" id="eventTitle" required>
                        </div>
                        <div class="mb-3">
                            <label for="eventDescription" class="form-label">Описание</label>
                            <textarea class="form-control" id="eventDescription" rows="3"></textarea>
                        </div>
                        <div class="mb-3">
                            <label for="eventStart" class="form-label">Начало</label>
                            <input type="datetime-local" class="form-control" id="eventStart" required>
                        </div>
                        <div class="mb-3">
                            <label for="eventEnd" class="form-label">Конец</label>
                            <input type="datetime-local" class="form-control" id="eventEnd" required>
                        </div>
                    </form>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
                    <button type="button" class="btn btn-primary" id="saveEvent">Сохранить</button>
                </div>
            </div>
        </div>
    </div>

    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <!-- Bootstrap JS -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <!-- FullCalendar JS -->
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.js"></script>
    <!-- Ваш скрипт -->
    <script src="script.js"></script>
</body>
</html>

2. Настройка FullCalendar и обработка событий

Создадим файл script.js, в котором настроим календарь и обработку событий:

javascript
Copy
document.addEventListener('DOMContentLoaded', function () {
    const calendarEl = document.getElementById('calendar');
    const calendar = new FullCalendar.Calendar(calendarEl, {
        initialView: 'dayGridMonth',
        selectable: true,
        editable: true,
        eventClick: function (info) {
            // Редактирование события
            openModal(info.event);
        },
        select: function (info) {
            // Создание нового события
            openModal({
                start: info.start,
                end: info.end
            });
        }
    });

    calendar.render();

    const eventModal = new bootstrap.Modal(document.getElementById('eventModal'));
    const eventForm = document.getElementById('eventForm');

    // Открытие модального окна
    function openModal(event) {
        document.getElementById('eventId').value = event.id || '';
        document.getElementById('eventTitle').value = event.title || '';
        document.getElementById('eventDescription').value = event.extendedProps?.description || '';
        document.getElementById('eventStart').value = event.start ? event.start.toISOString().slice(0, 16) : '';
        document.getElementById('eventEnd').value = event.end ? event.end.toISOString().slice(0, 16) : '';
        eventModal.show();
    }

    // Сохранение события
    document.getElementById('saveEvent').addEventListener('click', function () {
        const eventId = document.getElementById('eventId').value;
        const eventTitle = document.getElementById('eventTitle').value;
        const eventDescription = document.getElementById('eventDescription').value;
        const eventStart = document.getElementById('eventStart').value;
        const eventEnd = document.getElementById('eventEnd').value;

        const eventData = {
            id: eventId,
            title: eventTitle,
            description: eventDescription,
            start: eventStart,
            end: eventEnd
        };

        // Отправка данных через AJAX
        $.ajax({
            url: 'save_event.php',
            method: 'POST',
            data: eventData,
            success: function (response) {
                if (response.success) {
                    calendar.refetchEvents(); // Обновить календарь
                    eventModal.hide();
                } else {
                    alert('Ошибка: ' + response.message);
                }
            },
            error: function () {
                alert('Ошибка при отправке данных.');
            }
        });
    });
});

3. Обработка формы на стороне сервера (PHP)

Создадим файл save_event.php, который будет обрабатывать данные события:

php
Copy
<?php
header('Content-Type: application/json');

// Подключение к базе данных (пример для MySQL)
$host = 'localhost';
$db = 'calendar';
$user = 'root';
$pass = '';
$conn = new mysqli($host, $user, $pass, $db);

if ($conn->connect_error) {
    die(json_encode(['success' => false, 'message' => 'Ошибка подключения к базе данных.']));
}

// Получение данных из запроса
$id = $_POST['id'] ?? null;
$title = $_POST['title'] ?? '';
$description = $_POST['description'] ?? '';
$start = $_POST['start'] ?? '';
$end = $_POST['end'] ?? '';

// Валидация данных
if (empty($title) || empty($start)) {
    echo json_encode(['success' => false, 'message' => 'Заголовок и дата начала обязательны.']);
    exit;
}

// Сохранение или обновление события
if ($id) {
    // Редактирование существующего события
    $stmt = $conn->prepare("UPDATE events SET title = ?, description = ?, start = ?, end = ? WHERE id = ?");
    $stmt->bind_param('ssssi', $title, $description, $start, $end, $id);
} else {
    // Создание нового события
    $stmt = $conn->prepare("INSERT INTO events (title, description, start, end) VALUES (?, ?, ?, ?)");
    $stmt->bind_param('ssss', $title, $description, $start, $end);
}

if ($stmt->execute()) {
    echo json_encode(['success' => true]);
} else {
    echo json_encode(['success' => false, 'message' => 'Ошибка при сохранении события.']);
}

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

4. Создание таблицы в базе данных

Создайте таблицу events в базе данных:

sql
Copy
CREATE TABLE events (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    start DATETIME NOT NULL,
    end DATETIME
);

5. Загрузка событий в календарь

Добавьте в script.js загрузку событий из базы данных:

javascript
Copy
document.addEventListener('DOMContentLoaded', function () {
    const calendarEl = document.getElementById('calendar');
    const calendar = new FullCalendar.Calendar(calendarEl, {
        initialView: 'dayGridMonth',
        selectable: true,
        editable: true,
        events: 'load_events.php', // Загрузка событий
        eventClick: function (info) {
            openModal(info.event);
        },
        select: function (info) {
            openModal({
                start: info.start,
                end: info.end
            });
        }
    });

    calendar.render();
});

Создайте файл load_events.php для загрузки событий:

php
Copy
<?php
header('Content-Type: application/json');

$host = 'localhost';
$db = 'calendar';
$user = 'root';
$pass = '';
$conn = new mysqli($host, $user, $pass, $db);

if ($conn->connect_error) {
    die(json_encode([]));
}

$result = $conn->query("SELECT id, title, description, start, end FROM events");
$events = [];

while ($row = $result->fetch_assoc()) {
    $events[] = [
        'id' => $row['id'],
        'title' => $row['title'],
        'description' => $row['description'],
        'start' => $row['start'],
        'end' => $row['end']
    ];
}

echo json_encode($events);
$conn->close();
?>

Итог

Теперь у вас есть полнофункциональный календарь с возможностью создания, редактирования и сохранения событий через AJAX. Данные сохраняются в базе данных и загружаются при открытии календаря.

2 / 2
как добавить через select возможно повторяющие событий выбранной даты в календаре каждый день каждую неделю каждый месяц каждый год

Для добавления функционала повторяющихся событий в календарь (ежедневно, еженедельно, ежемесячно, ежегодно), нужно расширить логику как на стороне клиента (JavaScript), так и на стороне сервера (PHP). Вот пошаговая реализация:


1. Добавление выбора повторения в модальное окно

Добавим в модальное окно выпадающий список (<select>) для выбора типа повторения:

html
Copy
<div class="modal-body">
    <form id="eventForm">
        <input type="hidden" id="eventId">
        <div class="mb-3">
            <label for="eventTitle" class="form-label">Заголовок</label>
            <input type="text" class="form-control" id="eventTitle" required>
        </div>
        <div class="mb-3">
            <label for="eventDescription" class="form-label">Описание</label>
            <textarea class="form-control" id="eventDescription" rows="3"></textarea>
        </div>
        <div class="mb-3">
            <label for="eventStart" class="form-label">Начало</label>
            <input type="datetime-local" class="form-control" id="eventStart" required>
        </div>
        <div class="mb-3">
            <label for="eventEnd" class="form-label">Конец</label>
            <input type="datetime-local" class="form-control" id="eventEnd" required>
        </div>
        <div class="mb-3">
            <label for="eventRepeat" class="form-label">Повторение</label>
            <select class="form-select" id="eventRepeat">
                <option value="none">Не повторять</option>
                <option value="daily">Каждый день</option>
                <option value="weekly">Каждую неделю</option>
                <option value="monthly">Каждый месяц</option>
                <option value="yearly">Каждый год</option>
            </select>
        </div>
    </form>
</div>

2. Изменение логики сохранения события на стороне клиента

В файле script.js добавим обработку выбора повторения и отправку данных на сервер:

javascript
Copy
document.getElementById('saveEvent').addEventListener('click', function () {
    const eventId = document.getElementById('eventId').value;
    const eventTitle = document.getElementById('eventTitle').value;
    const eventDescription = document.getElementById('eventDescription').value;
    const eventStart = document.getElementById('eventStart').value;
    const eventEnd = document.getElementById('eventEnd').value;
    const eventRepeat = document.getElementById('eventRepeat').value;

    const eventData = {
        id: eventId,
        title: eventTitle,
        description: eventDescription,
        start: eventStart,
        end: eventEnd,
        repeat: eventRepeat
    };

    // Отправка данных через AJAX
    $.ajax({
        url: 'save_event.php',
        method: 'POST',
        data: eventData,
        success: function (response) {
            if (response.success) {
                calendar.refetchEvents(); // Обновить календарь
                eventModal.hide();
            } else {
                alert('Ошибка: ' + response.message);
            }
        },
        error: function () {
            alert('Ошибка при отправке данных.');
        }
    });
});

3. Обработка повторяющихся событий на стороне сервера

В файле save_event.php добавим логику для создания повторяющихся событий:

php
Copy
<?php
header('Content-Type: application/json');

// Подключение к базе данных
$host = 'localhost';
$db = 'calendar';
$user = 'root';
$pass = '';
$conn = new mysqli($host, $user, $pass, $db);

if ($conn->connect_error) {
    die(json_encode(['success' => false, 'message' => 'Ошибка подключения к базе данных.']));
}

// Получение данных из запроса
$id = $_POST['id'] ?? null;
$title = $_POST['title'] ?? '';
$description = $_POST['description'] ?? '';
$start = $_POST['start'] ?? '';
$end = $_POST['end'] ?? '';
$repeat = $_POST['repeat'] ?? 'none';

// Валидация данных
if (empty($title) || empty($start)) {
    echo json_encode(['success' => false, 'message' => 'Заголовок и дата начала обязательны.']);
    exit;
}

// Функция для сохранения события
function saveEvent($conn, $title, $description, $start, $end) {
    $stmt = $conn->prepare("INSERT INTO events (title, description, start, end) VALUES (?, ?, ?, ?)");
    $stmt->bind_param('ssss', $title, $description, $start, $end);
    return $stmt->execute();
}

// Сохранение события
if ($repeat === 'none') {
    // Одиночное событие
    if (saveEvent($conn, $title, $description, $start, $end)) {
        echo json_encode(['success' => true]);
    } else {
        echo json_encode(['success' => false, 'message' => 'Ошибка при сохранении события.']);
    }
} else {
    // Повторяющееся событие
    $startDate = new DateTime($start);
    $endDate = new DateTime($end);
    $interval = null;

    switch ($repeat) {
        case 'daily':
            $interval = new DateInterval('P1D'); // Каждый день
            break;
        case 'weekly':
            $interval = new DateInterval('P1W'); // Каждую неделю
            break;
        case 'monthly':
            $interval = new DateInterval('P1M'); // Каждый месяц
            break;
        case 'yearly':
            $interval = new DateInterval('P1Y'); // Каждый год
            break;
    }

    // Сохраняем события на год вперед
    $maxDate = (new DateTime())->modify('+1 year');
    while ($startDate <= $maxDate) {
        if (!saveEvent($conn, $title, $description, $startDate->format('Y-m-d H:i:s'), $endDate->format('Y-m-d H:i:s'))) {
            echo json_encode(['success' => false, 'message' => 'Ошибка при сохранении повторяющегося события.']);
            exit;
        }
        $startDate->add($interval);
        $endDate->add($interval);
    }

    echo json_encode(['success' => true]);
}

$conn->close();
?>

4. Загрузка повторяющихся событий в календарь

В файле load_events.php изменений не требуется, так как все события уже сохраняются в базе данных как отдельные записи. FullCalendar автоматически отобразит их.


5. Пример базы данных

Таблица events должна содержать поля для хранения данных о событиях:

sql
Copy
CREATE TABLE events (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    start DATETIME NOT NULL,
    end DATETIME
);

Итог

Теперь пользователь может создавать повторяющиеся события:

  • Ежедневно: Событие будет повторяться каждый день.

  • Еженедельно: Событие будет повторяться каждую неделю.

  • Ежемесячно: Событие будет повторяться каждый месяц.

  • Ежегодно: Событие будет повторяться каждый год.

Все события сохраняются в базе данных и отображаются в календаре.

Fatal error: Uncaught TypeError: DateTime::add(): Argument #1 ($interval) must be of type DateInterval, null given

Ошибка Fatal error: Uncaught TypeError: DateTime::add(): Argument #1 ($interval) must be of type DateInterval, null given возникает, потому что переменная $interval не была инициализирована для какого-то значения $repeat. Это может произойти, если значение $repeat не соответствует ни одному из случаев в switch.

Чтобы исправить эту ошибку, нужно:

  1. Убедиться, что значение $repeat всегда соответствует одному из ожидаемых вариантов (none, daily, weekly, monthly, yearly).

  2. Добавить обработку по умолчанию в switch, чтобы избежать null в $interval.

Вот исправленный код:

Исправленный код для save_event.php

php
Copy
<?php
header('Content-Type: application/json');

// Подключение к базе данных
$host = 'localhost';
$db = 'calendar';
$user = 'root';
$pass = '';
$conn = new mysqli($host, $user, $pass, $db);

if ($conn->connect_error) {
    die(json_encode(['success' => false, 'message' => 'Ошибка подключения к базе данных.']));
}

// Получение данных из запроса
$id = $_POST['id'] ?? null;
$title = $_POST['title'] ?? '';
$description = $_POST['description'] ?? '';
$start = $_POST['start'] ?? '';
$end = $_POST['end'] ?? '';
$repeat = $_POST['repeat'] ?? 'none';

// Валидация данных
if (empty($title) || empty($start)) {
    echo json_encode(['success' => false, 'message' => 'Заголовок и дата начала обязательны.']);
    exit;
}

// Функция для сохранения события
function saveEvent($conn, $title, $description, $start, $end) {
    $stmt = $conn->prepare("INSERT INTO events (title, description, start, end) VALUES (?, ?, ?, ?)");
    $stmt->bind_param('ssss', $title, $description, $start, $end);
    return $stmt->execute();
}

// Сохранение события
if ($repeat === 'none') {
    // Одиночное событие
    if (saveEvent($conn, $title, $description, $start, $end)) {
        echo json_encode(['success' => true]);
    } else {
        echo json_encode(['success' => false, 'message' => 'Ошибка при сохранении события.']);
    }
} else {
    // Повторяющееся событие
    $startDate = new DateTime($start);
    $endDate = new DateTime($end);
    $interval = null;

    switch ($repeat) {
        case 'daily':
            $interval = new DateInterval('P1D'); // Каждый день
            break;
        case 'weekly':
            $interval = new DateInterval('P1W'); // Каждую неделю
            break;
        case 'monthly':
            $interval = new DateInterval('P1M'); // Каждый месяц
            break;
        case 'yearly':
            $interval = new DateInterval('P1Y'); // Каждый год
            break;
        default:
            // Если значение $repeat не распознано, завершаем с ошибкой
            echo json_encode(['success' => false, 'message' => 'Неверный тип повторения.']);
            exit;
    }

    // Сохраняем события на год вперед
    $maxDate = (new DateTime())->modify('+1 year');
    while ($startDate <= $maxDate) {
        if (!saveEvent($conn, $title, $description, $startDate->format('Y-m-d H:i:s'), $endDate->format('Y-m-d H:i:s'))) {
            echo json_encode(['success' => false, 'message' => 'Ошибка при сохранении повторяющегося события.']);
            exit;
        }
        $startDate->add($interval);
        $endDate->add($interval);
    }

    echo json_encode(['success' => true]);
}

$conn->close();
?>

Что изменено:

  1. Добавлен default в switch:

    • Если значение $repeat не соответствует ни одному из ожидаемых вариантов (daily, weekly, monthly, yearly), выполнится блок default.

    • В этом случае скрипт завершится с ошибкой: Неверный тип повторения.

  2. Проверка значения $repeat:

    • Если $repeat не передано или передано неверное значение, скрипт не попытается создать DateInterval с null.


Пример запроса с неверным значением repeat

Если в запросе передано неверное значение repeat, например invalid, сервер вернет ошибку:

json
Copy
{
  "success": false,
  "message": "Неверный тип повторения."
}

Пример запроса с корректным значением repeat

Если в запросе передано корректное значение, например weekly, сервер создаст повторяющиеся события:

json
Copy
{
  "success": true
}

Как избежать ошибок в будущем

  1. Валидация на стороне клиента:

    • Убедитесь, что в <select> для выбора повторения передаются только допустимые значения (none, daily, weekly, monthly, yearly).

  2. Валидация на стороне сервера:

    • Всегда проверяйте входные данные перед использованием.

  3. Логирование:

    • Добавьте логирование ошибок, чтобы отслеживать неожиданные ситуации.


Теперь ошибка DateTime::add(): Argument #1 ($interval) must be of type DateInterval, null given больше не возникнет, так как $interval всегда будет корректным объектом DateInterval или выполнение скрипта завершится с ошибкой.

New chat
DeepThink (R1)
Search
AI-generated, for reference only