Этот сниппет обработчика ajax запросов я часто использую в своих проектах.
Представим себе такую задачу: необходимо реализовать CRUD (create, update, delete) операции элементов инфоблока Битрикс. При этом сами операции должны выполняться от имени такого пользователя, который:
- авторизован на сайте
- принадлежит определённой группе пользователей
Операции должны инициироваться POST обращением по Ajax к определённому скрипту (обработчику аякс запроса)
Решение
С одной стороны можно нагородить отдельные php скрипты-обработчики вида
- create.php
- update.php
- delete.php
Но в этом случае мы столкнёмся с дублированием кода в каждом скрипте, т.к. помимо самой операции нужно:
- проверять, авторизован ли пользователь
- проверить, принадлежит ли он той группе пользователей, которая требуется
- как-то сообщать юзеру, что операция выполнена с ошибкой, если таковая появится
Именно поэтому вместо такой реализации можно применить следующую идею — реализовать единый обработчик, который на входе будет принимать:
- идентификатор метода (требуемой операции)
- значения параметров, необходимых для выполнения операции
На выходе — массив данных, состоящий из двух элементов:
<?php header('Content-Type: application/json'); require_once($_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/main/include/prolog_before.php"); class CRUD_IBlock { //ID инфоблока с которым работаем protected $iblock_id = 56; //ID группы пользователя protected $user_group = 36; //текстовая информация по умолчанию на выходе - пустая protected $data = ''; //ошибка выполнения операции по умолчания - есть. её текстовая расшифровка - пустая protected $error = ['status' => true, 'error_text'=>'']; function __construct() { //если требуемый метод присутствует в нашем классе if (method_exists($this, $_POST['method'])){ global $USER; //проверяем, авторизован ли пользователь и принадлежит ли он требуемой группе пользователей if ($USER->IsAuthorized() && in_array($this->user_group, $USER->GetUserGroupArray())){ //подключаем модуль работы с инфоблоками CModule::IncludeModule("iblock"); //преобразовываем спец. символы в HTML сущности для защиты от SQL инъекций $operation_data = []; if (is_array($_POST['data'])){ foreach ($_POST['data'] as $key=>$value) { $operation_data[htmlspecialcharsbx($key)] = htmlspecialcharsbx($value); } } $method = (string)$_POST['method']; //вызываем метод c HTML безопасным представлением данных для выполнения операции $this->$method($operation_data); } else { //если пользователь не авторизован или не принадлежит нужной группе пользователей $this->error['error_text'] = 'Пожалуйста, авторизуйтесь под своей учетной записью.'; } } else { //если вызвали несуществующий метод $this->error['error_text'] = "Метод ".$_POST['method']." отсутствует в классе CRUD_IBlock"; } //отпрвляем JSON с данными echo json_encode(['data'=>$this->data, 'error'=>$this->error]); } protected function Create($operation_data){ // создаём элемент. данные для создания берём из массива $operation_data // ... // успешность создания элемента записываем в $result if ($result){ $this->error['status'] = false; $this->data = 'Элемент успешно создан'; } else { $this->error['message'] = 'Описание причины невозможности создать элемент'; } } protected function Update($operation_data){ // обновляем элемент. данные для обновления берём из массива $operation_data // ... // успешность обновленния элемента записываем в $result if ($result){ $this->error['status'] = false; $this->data = 'Элемент успешно обновлен'; } else { $this->error['message'] = 'Описание причины невозможности обновить элемент'; } } protected function Delete($operation_data){ // удаляем элемент. данные для удаления берём из массива $operation_data // ... // успешность удаления элемента записываем в $result if ($result){ $this->error['status'] = false; $this->data = 'Элемент успешно удален'; } else { $this->error['message'] = 'Описание причины невозможности удалить элемент'; } } } $crud = new CRUD_IBlock();
Если оперировать вышеприведённым кодом, то на вход подаём:
- method: название метода необходимой операции
- data: данные, требуемые для выполнения операции
На выходе получаем:
- data: мета данные после успешного выполнения операции
- error: массив из двух элементов — первый с ключем status: есть ли ошибка, второй с ключем message: текстовая расшифровка ошибки
Как пользоваться
Если использовать JQuery ajax запрос, то его примерный общий вид будет следующий:
let data = { //какие-то данные для выполнения операции }; $.ajax({ url:'url_обработчика', type:"POST", dataType: 'json', data: { method: 'название_метода', data: data }, success: function(result){ //операция выполнена успешно if (!result.error.status){ //мета данные в результате успешного выполнения операции console.log (result.data); } //операция выполнена с ошибкой else { //расшифровка ошибки console.log (result.error.message); } } })
Собственно, вот и вся магия.