dhtmlxScheduler с PHP
В этом руководстве приведены все необходимые детали для создания планировщика (Scheduler) на PHP без использования каких-либо фреймворков.
В качестве хранилища данных используется MySQL, а для доступа к базе данных применяется интерфейс PDO. Для выполнения шагов потребуется PHP версии 5.4 или выше с включённым расширением PDO_MYSQL, а также MySQL или MariaDB.
Если вас интересует серверная интеграция с использованием других платформ или фреймворков, доступны руководства для:
- dhtmlxScheduler с ASP.NET Core
- dhtmlxScheduler с ASP.NET MVC
- dhtmlxScheduler с Node.js
- dhtmlxScheduler с PHP: Slim
- dhtmlxScheduler с PHP:Laravel
- dhtmlxScheduler с SalesForce LWC
- dhtmlxScheduler с Ruby on Rails
- dhtmlxScheduler с dhtmlxConnector
Также вы можете ознакомиться с полной демонстрацией на GitHub и следовать пошаговым инструкциям для создания приложения.
Полный исходный код доступен на GitHub.
Шаг 1. Создание проекта
Начните с создания новой директории для вашего приложения.
Создайте пустую папку и назовите её scheduler-howto-php-plain.
Шаг 2. Добавление Scheduler на страницу
Далее создайте страницу, на которой будет размещён планировщик.
Внутри папки scheduler-howto-php-plain создайте файл index.html и добавьте следующий код:
<!doctype html>
<html>
<head>
<title> Getting started with dhtmlxScheduler</title>
<meta charSet="utf-8"/>
<script src="https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.js"></script>
<link href="https://cdn.dhtmlx.com/scheduler/edge/dhtmlxscheduler.css"
rel="stylesheet" type="text/css" charSet="utf-8">
<style>
html, body{
margin:0px;
padding:0px;
height:100%;
overflow:hidden;
}
</style>
</head>
<body>
<div id="scheduler_here" className="dhx_cal_container">
<div className="dhx_cal_navline">
<div className="dhx_cal_prev_button"> </div>
<div className="dhx_cal_next_button"> </div>
<div className="dhx_cal_today_button"></div>
<div className="dhx_cal_date"></div>
<div className="dhx_cal_tab" name="day_tab"></div>
<div className="dhx_cal_tab" name="week_tab"></div>
<div className="dhx_cal_tab" name="month_tab"></div>
</div>
<div className="dhx_cal_header"></div>
<div className="dhx_cal_data"></div>
</div>
<script>
scheduler.init('scheduler_here', new Date(2019,0,20), "week");
scheduler.load("data/api.php");
</script>
</body>
</html>
После запуска приложения планировщик должен отобразиться на странице:

Шаг 3. Подготовка базы данных
На данный момент планировщик пуст. Следующий шаг - создать базу данных и подключить её к приложению.
Создание базы данных
Вы можете создать базу данных через любой удобный клиент MySQL (например, phpMyAdmin) или через командную строку. Используйте следующий SQL-код для создания новой базы данных и таблицы для событий календаря:
CREATE DATABASE IF NOT EXISTS `scheduler_howto_php`;
USE `scheduler_howto_php`;
DROP TABLE IF EXISTS `events`;
CREATE TABLE `events` (
`id` int(11) AUTO_INCREMENT,
`start_date` datetime NOT NULL,
`end_date` datetime NOT NULL,
`text` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET="utf8;"
Если вы предпочитаете использовать консоль MySQL, сохраните приведённый выше SQL в файл dump.sql, затем выполните команду:
$ mysql -uuser -ppass scheduler < mysql_dump.sql
Шаг 4. Загрузка данных
После подготовки базы данных можно приступить к загрузке данных в планировщик.
Создайте новую папку с именем data в директории вашего проекта.
Сначала определите параметры подключения к базе данных в конфигурационном файле data/config.php:
<?php
$dsn = "mysql:host=localhost;dbname=scheduler_howto_php";
$username = "root";
$password = "";
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'",
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
);
Обязательно замените "localhost", "scheduler_howto_php", "root" и "" на ваши реальные параметры подключения к базе данных.
Далее добавьте PHP-скрипт, который будет использоваться клиентом для загрузки данных из базы и сохранения изменений в планировщике.
Создайте файл api.php в папке data и начните с открытия соединения с базой данных:
<?php
require_once("config.php");
$db = new PDO($dsn, $username, $password, $options);
Затем реализуйте функцию для получения событий из базы данных:
function read($db, $requestParams){
$queryParams = [];
$queryText = "SELECT * FROM `events`";
$query = $db->prepare($queryText);
$query->execute($queryParams);
$events = $query->fetchAll();
return $events;
}
Далее создайте обработчик запросов для ответа на входящие запросы:
switch ($_SERVER["REQUEST_METHOD"]) {
case "GET":
$result = read($db, $_GET);
break;
case "POST":
// we'll implement this later
break;
default:
throw new Exception("Unexpected Method");
break;
}
header("Content-Type: application/json");
echo json_encode($result);
Если вы добавите несколько событий в базу данных, они появятся в планировщике.
Динамическая загрузка
В текущей реализации планировщик загружает все записи о событиях из базы данных за один раз. Такой подход подходит, если объём данных небольшой. Однако для приложений вроде систем бронирования или планирования, где со временем накапливается много записей, объём передаваемых данных может значительно увеличиться. Через несколько месяцев активного использования приложение может загружать несколько мегабайт событий при каждом открытии страницы.
Этого можно избежать, включив динамическую загрузку. В этом режиме планировщик отпра вляет параметры с отображаемым диапазоном дат, а сервер возвращает только те события, которые попадают в этот диапазон. Каждый раз при переходе пользователя к другому диапазону дат планировщик загружает только соответствующие данные.
Чтобы включить динамическую загрузку на клиенте, используйте опцию setLoadMode и укажите "day", "week" или "month". Например, добавьте в клиентский код:
scheduler.init("scheduler_here", new Date(2019, 0, 20), "week");
scheduler.setLoadMode("day"); /*!*/
// загрузка данных с сервера
scheduler.load("data/api.php");
На сервере обработайте это, изменив функцию read следующим образом:
function read($db, $requestParams){
$queryParams = [];
$queryText = "SELECT * FROM `events`";
// обработка динамической загрузки
if (isset($requestParams["from"]) && isset($requestParams["to"])) { /*!*/
$queryText .= " WHERE `end_date`>=? AND `start_date` < ?;"; /*!*/
$queryParams = [$requestParams["from"], $requestParams["to"]]; /*!*/
} /*!*/
$query = $db->prepare($queryText);
$query->execute($queryParams);
$events = $query->fetchAll();
return $events;
}
Шаг 5. Сохранение изменений
Реализация обработчиков на сервере
На данный момент планировщик может только читать данные с сервера. Следующий шаг - реализовать сохранение изменений обратно в базу данных.
Клиент работает в режиме JSON, отправляя POST-запросы для выполнения действий над событиями. Подробнее о формате запросов и маршрутах читайте в Интеграция с серверной стороной.
Добавьте функции для создания, обновления и удаления событий в базе данных.
В файле data/api.php добавьте следующее:
// создание нового события
function create($db, $event){
$queryText = "INSERT INTO `events` SET
`start_date`=?,
`end_date`=?,
`text`=?";
$queryParams = [
$event["start_date"],
$event["end_date"],
$event["text"]
];
$query = $db->prepare($queryText);
$query->execute($queryParams);
return $db->lastInsertId();
}
// обновление события
function update($db, $event, $id){
$queryText = "UPDATE `events` SET
`start_date`=?,
`end_date`=?,
`text`=?
WHERE `id`=?";
$queryParams = [
$event["start_date"],
$event["end_date"],
$event["text"],
$id
];
$query = $db->prepare($queryText);
$query->execute($queryParams);
}
// удаление события
function delete($db, $id){
$queryText = "DELETE FROM `events` WHERE `id`=? ;";
$query = $db->prepare($queryText);
$query->execute([$id]);
}
Затем обновите обработчик POST-запросов для использования этих функций:
$db = new PDO($dsn, $username, $password, $options);
switch ($_SERVER["REQUEST_METHOD"]) {
case "GET":
$result = read($db, $_GET);
break;
case "POST": /*!*/
$requestPayload = json_decode(file_get_contents("php://input")); /*!*/
$id = $requestPayload->id; /*!*/
$action = $requestPayload->action; /*!*/
$body = (array) $requestPayload->data; /*!*/
$result = [ /*!*/
"action" => $action /*!*/
]; /*!*/
if ($action == "inserted") {; /*!*/
$databaseId = create($db, $body); /*!*/
$result["tid"] = $databaseId; /*!*/
} elseif($action == "updated") { /*!*/
update($db, $body, $id); /*!*/
} elseif($action == "deleted") { /*!*/
delete($db, $id); /*!*/
} /*!*/
break; /*!*/
default:
throw new Exception("Unexpected Method");
break;
}
header("Content-Type: application/json");
echo json_encode($result);
При создании нового события его идентификатор из базы данных возвращается клиенту в свойстве tid объекта ответа. В ответе JSON могут быть добавлены и другие свойства, которые можно использовать на стороне клиента.