JResponseJson – возвращаем данные в формате JSON
Общая информация
Класс JResponseJson
появился в CMS версии 3.x. Он предоставляет общий интерфейс для переменных ответа (например, на Ajax запросы). Класс расположен в директории /libraries/cms/response.
В основном он используется в контроллерах компонентов и дает следующие преимущества:
- Используя флаг
success
, JavaScript код (Mootools JRequest.JSON или jQuery.getJSON) может проверить, удачно ли завершилась задача. Если запрос неудачен, может быть использовано событие ошибки JavaScript API. - Данные (если есть) будут доступны в свойстве
data
в виде JSON-объекта - Дополнительно можно установить сообщение ответа через свойство
message
. - Все собранные сообщения очереди
JApplication
будут автоматически направлены в свойствоmessages
.
Еде одним преимуществом является то, что больше нет надобности в закрытии приложения ($app->close()
), если Ajax запрос был сделан с помощью format=json
. За вас это сделает существующее API.
Как использовать
Наиболее распространённый случай
Рассмотрим пример контроллера:
class MyController extends JControllerLegacy { public function someTask() { try { $app = JFactory::getApplication(); $anyParam = $this->input->get('anyparam'); $result = $this->getModel('example')->createSomething($anyParam); echo new JResponseJson($result); $app->close(); } catch(Exception $e) { echo new JResponseJson($e); $app->close(); } } }
Здесь возвращаемое значение $result
просто передается в новый объект JResponseJson
и выводится с помощью echo
. Это автоматически создает строку в формате JSON:
{"success":true,"message":null,"messages":null,"data": {"myfirstcustomparam":1,"mysecondcustomparam":42, ...}}
В data
вы можете передавать массив, объект или значение, при этом флаг success
будет автоматически установлен в true
.
В нашем случае, если случится какое-то исключение в модели, то оно просто передается напрямую в объект JResponseJson
, что приведет к следующим выходным данным:
{"success":false,"message":"Это сообщение исключения","messages":null,"data":null}
Так как это исключение, флаг success
был автоматически установлен в false
, и сообщение исключения стало основным сообщением ответа.
Дополнительные опции
Если первым аргументом конструктора объекта JResponseJson
передается не исключение, то вы можете указать произвольное основное сообщение ответа, передавая его вторым аргументом $message
:
echo new JResponseJson($result, JText::_('COM_COMPONENT_MY_TASK_SUCCESS'));
Это создаст следующее:
{"success":true,"message":"Запрос завершен успешно.","messages":null,"data": {"myfirstcustomparam":1,"mysecondcustomparam":42, ...}}
Вы можете вручную установить флаг ошибки в false
с помощью третьего аргумента $error
:
echo new JResponseJson($result, JText::_('COM_COMPONENT_MY_TASK_ERROR'), true);
Вот что мы получим на выходе:
{"success":false,"message":"Произошлаошибка.","messages":null,"data": {"myfirstcustomparam":1,"mysecondcustomparam":42, ...}}
Обратите внимание на то, что таким образом вы можете передать назад данные.
Независимо от того, был ли ответ с ошибкой или удачным, класс JResponseJson
отправляет все сообщения обратно клиенту, где они собираются в объекте приложения:
$app = JFactory::getApplication(); //Какой-то код ($result = ...) $app->enqueueMessage('Эта часть выполнена успешна'); // Еще код $app->enqueueMessage('А здесь было предупреждение','warning'); echo new JResponseJson($result, 'Главное сообщение ответа');
Вот как будет выглядеть ответ:
{"success":true,"message":"Главное сообщение ответа","messages":"<<все сообщения приложения>>","data":{"myfirstcustomparam":1,"mysecondcustomparam":42, ...}}
Преимущество такого подхода вы увидите ниже в разделе JavaScript.
Если же вы не хотите посылать назад сообщения, просто установите четвертый аргумент $ignoreMessages
конструктора в значение true
.
Соответствующий JavaScript код
Ниже приведены примеры JavaScript кода, который может быть использован на клиентской стороне вместе с JResponseJson
на стороне сервера.
Пример на MooTools
var req = new Request.JSON({ method: 'post', url: 'index.php?option=com_component&task=mycontroller.someTask&format=json', onSuccess: function(r) { if (!r.success && r.message) { // Флаг успеха установлен в 'false' и есть основное сообщение ответа. // Вы можете вывести его в alert или в HTML элемент. alert(r.message); } if (r.messages) { // Все сообщения очереди объекта приложения могут быть выведены с помощью // соответствующей функции Joomla API. Они автоматически отобразятся // в секции messages шаблона. Joomla.renderMessages(r.messages); } if (r.data) { // Получаем доступ к данным вашего ответа alert(r.data.myfirstcustomparam); alert(r.data.mysecondcustomparam); } }.bind(this), onFailure: function(xhr) { // Ajax запрос был неуспешен. JResponseJson не вызван. alert('Ошибка Ajax запроса!'); }.bind(this), onError: function(text, error) { // Получен ответ от сервера, но это не валидные JSON данные // (иногда такое случается при ошибках PHP во время запроса). alert(error + "\n\n" + text); }.bind(this) }); req.post('anyparam=myvalue');
Пример на jQuery
$.getJSON('index.php?option=com_component&task=mycontroller.someTask&format=json', { data: data }) .done(function(r) { if (!r.success && r.message) { alert(r.message); } if (r.messages) { Joomla.renderMessages(r.messages); } if (r.data) { alert(r.data.myfirstcustomparam); alert(r.data.mysecondcustomparam); } }) .fail(function() { alert('Ошибка Ajax запроса!'); }) .always(function() { alert('Ajax запрос завершен'); });
Лучшие практики
Как мы видели выше, код контроллера может быть очень простым, благодаря классу JResponseJson
. Модель обрабатывает данные, которые потом могут быть направлены непосредственно в объект JResponseJson
. Контроллер лучше всего сохранять в файле mycontroller.json.php
и размещать его в папке controllers
. Таким образом, этот контроллер будет вызван автоматически, если URL содержит format=json
.
Также не забывайте, что нет надобности в закрытии приложения (например, $app->close()
), так как Joomla API сделает это за вас.
Удачной разработки!