📤 Класс Response
Класс Response отвечает за вывод данных из контроллера. С его помощью можно вернуть текст, HTML, JSON, объекты, шаблоны, перенаправления и коды ошибок.
⚡ Быстрый старт
Вы можете создать ответ вручную:
$response = new Response();
$response->json(['name' => 'Саша']);Но гораздо удобнее использовать хелпер response():
response(['name' => 'Саша']);Он автоматически определяет тип содержимого — массив, объект или текст — и возвращает соответствующий ответ.
🧪 Пример использования в контроллере
Route::get('/', function () {
return response()->json([
'message' => 'Добро пожаловать!',
'version' => '1.0.0',
]);
});🧾 Методы ответа
📄 text($text, $status = 200, $headers = [])
Возвращает простой текст.
Route::get('/text', function () {
return response()->text('Простой текстовый ответ');
});🌐 html($html, $status = 200, $headers = [])
Возвращает HTML-контент. Вставляет скрипты MODX из $modx->getRegisteredClientStartupScripts() и $modx->getRegisteredClientScripts() в </head> и </body>.
Route::get('/html', function () {
return response()->html('<!DOCTYPE html><html><head></head><body><h1>Привет</h1></body></html>');
});🔢 json(array $data, $status = 200, $headers = [])
Возвращает JSON с автоматической установкой заголовка Content-Type: application/json.
Route::get('/json', function () {
return response()->json([
'success' => true,
'user' => ['name' => 'Саша', 'age' => 30],
]);
});🧱 object($object, $status = 200, $headers = [])
Конвертирует объект или коллекцию xPDOObject в массив и возвращает как JSON. Поддерживает одиночные объекты и xPDOIterator.
Route::get('/user', function () {
$user = $modx->getObject(\modUser::class, 1);
// или $user = query(\modUser::class)->find(1)
return response()->object($user);
});Route::get('/users', function () {
$users = $modx->getIterator(\modUser::class);
// или $users = query(\modUser::class)->get()
return response()->object($users);
});🖼️ view($template, array $data = [])
Рендерит шаблон с помощью view() и возвращает как HTML.
Route::get('/home', function () {
return response()->view('home', ['title' => 'Главная страница']);
});Шаблон можно задать как
@INLINE,@FILE,file:, чанк или путь.
🔁 Перенаправления
В PageBlocks вы можете создавать HTTP-редиректы с помощью метода redirect(...) у объекта Response:
return response()->redirect('/dashboard');Но чаще используется глобальный хелпер redirect() — он короче и предоставляет доступ ко всем методам класса Redirect:
return redirect('/dashboard'); // обычный редирект
return redirect()->route('profile.show'); // именованный маршрут
return redirect()->back(); // назад🔀 redirect($url, $status = 302)
Простой редирект на указанный URL.
Пример в контроллере:
Route::get('/go-home', function () {
return redirect('/');
});🔙 back($fallback = '/', $status = 302)
Редирект на предыдущую страницу (HTTP_REFERER), или на $fallback, если REFERER отсутствует.
Пример:
Route::post('/form', function () {
// Обработка данных...
return redirect()->back();
});♻️ refresh($status = 302)
Обновляет текущий URL.
Пример:
Route::get('/refresh', function () {
return redirect()->refresh();
});🏠 home($status = 302)
Редирект на главную страницу (/):
Пример:
Route::get('/logout', function () {
// Очистка сессии...
return redirect()->home();
});🧭 route($name, $parameters = [], $status = 302)
Редиректит на именованный маршрут.
Пример:
Route::get('/profile/{id}', ...)->name('profile.show');
Route::post('/profile/save', function () {
// Сохранение...
return redirect()->route('profile.show', ['id' => 42]);
});→ Если найден маршрут /profile/{id}, будет редирект на /profile/42.
❗ Если указанный маршрут не найден — будет вызван abort(500).
🧨 intended($defaultUrl = '/', $status = 302)
Редиректит на сохранённый адрес из $_SESSION['_intended'], или на $defaultUrl, если он не задан.
Где может использоваться:
Route::post('/login', function () {
// Проверка логина...
return redirect()->intended('/');
});Когда это работает:
Если вы заранее сохранили $_SESSION['_intended'] при попытке доступа к защищённой странице:
// Middleware или логика защиты:
$_SESSION['_intended'] = $_SERVER['REQUEST_URI'];
return redirect()->route('login');🔐 secure($url, $status = 302)
Редиректит на HTTPS-версию URL. Полезно, если нужно принудительно перевести пользователя на защищённое соединение.
Пример:
Route::get('/secure', function () {
return redirect()->secure('profile/edit');
});Результат: https://example.com/profile/edit
❌ error($code = 404, $text = '')
Простой способ вернуть ошибку через redirect():
Route::get('/admin', function () {
if (!auth('mgr')) {
return redirect()->error(403, 'Доступ запрещён');
}
});🛑 Немедленное завершение — abort()
Глобальный хелпер abort() вызывает response()->abort(...)->send() и сразу завершает выполнение, отдав готовую страницу с шаблоном.
Route::get('/admin', function () {
if (!auth('mgr')) {
abort(403, 'Доступ запрещён');
}
return view('admin.panel');
});⚠️ Не требует return, так как сразу отправляет заголовки и рендерит страницу.
📌 Поддерживаются стандартные HTTP-коды: 403, 404, 503 и т.д. Для них используются системные страницы MODX:
- 403 →
unauthorized_page - 404 →
error_page - 503 →
site_unavailable_page
Если код не найден в системных страницах, то создаётся временный ресурс с текстом ошибки.
📦 Если шаблон ошибки для кода существует (core/App/elements/templates/errors/{code}.tpl) — он будет использован. В противном случае подключается базовый шаблон:
templates/base.tplПример использования без параметров (возвращает 404 Not Found):
Route::get('/admin', function () {
if (!auth('mgr')) {
abort(); // вернёт 404 страницу
}
return view('admin.panel');
});📦 Хелпер response
function response($content = '', int $status = 200, array $headers = []): ResponseПоведение:
- массив →
json(...) - объект →
object(...) - строка →
text(...)
Примеры:
return response(['ok' => true]); // JSON
return response($user); // xPDOObject → JSON
return response('Hello, world!'); // Text📎 Скачивание файлов
📥 download($file, $name = null, $headers = [])
Позволяет скачать файл с сервера. Устанавливает корректные заголовки Content-Type, Content-Disposition, Content-Length и читает содержимое файла.
Route::get('/download', function () {
return response()->download('assets/files/manual.pdf');
});Можно переименовать файл при загрузке:
Route::get('/download-invoice', function () {
return response()->download('assets/files/invoice_2025.pdf', 'invoice.pdf');
});Если файл не найден — возвращается 404 File not found..
✅ Универсальные ответы
Эти методы автоматически выбирают формат ответа — HTML или JSON — в зависимости от request()->expectsJson().
✅ success($message = '', $redirect = '')
Возвращает успешный ответ. Работает в двух режимах:
- 🔁 если
expectsJson()→ возвращает JSON:
{
"success": true,
"message": "Успешно сохранено",
"errors": [],
"redirect": "/dashboard"
}- 📦 если нет → редиректит назад (
back()илиredirect(...)), добавляет флеш-сообщение и старые данные (withInput()).
Route::post('/form', function () {
// сохранение данных...
return response()->success('Данные сохранены', '/profile');
});❌ error($message = '', $errors = [], $status = 422)
Возвращает ответ с ошибкой. Поведение аналогично:
- 🔁 JSON:
{
"success": false,
"message": "Ошибка валидации",
"errors": {
"email": "Неверный формат"
},
"redirect": ""
}- 📦 HTML: редирект назад с флеш-сообщением,
withErrors()иwithInput().
Route::post('/form', function () {
$errors = ['email' => 'Неверный формат'];
return response()->error('Проверьте форму', $errors);
});➕ append(array $data)
Дополняет JSON-ответ дополнительными данными. Используется в связке с success() или error().
Route::post('/form', function () {
return response()
->append(['debug' => true])
->success('ОК');
});Результат:
{
"success": true,
"message": "ОК",
"errors": [],
"redirect": "",
"debug": true
}👜 withBag
Метод withBag($name) позволяет сгруппировать флеш-данные под именем мешка. Это удобно, если у вас несколько форм на странице.
✅ Пример для success()
return response()
->withBag('auth')
->success('Вы успешно вошли!');В шаблоне:
{$success_message.auth} {* Выведет: Вы успешно вошли! *}❌ Пример для error()
return response()
->withBag('auth')
->error('Ошибка входа', [
'email' => 'Почта не найдена',
'password' => 'Неверный пароль',
]);В шаблоне:
{$error_message.auth} {* Основное сообщение *}
{$errors.auth.email} {* Отдельное сообщение для поля email *}
{$errors.auth.password} {* Отдельное сообщение для поля password *}
{$old_input.auth.email} {* Старое значение поля email *}Без withBag() данные будут доступны без вложенности:
{$error_message}
{$errors.email}
{$old_input.email}🧾 Работа с заголовками
Класс Response позволяет гибко управлять HTTP-заголовками: добавлять, удалять, получать.
➕ header($name, $value)
Добавляет один заголовок (сокращённый синоним setHeader()):
return response()
->text('OK')
->header('X-Custom-Header', 'value123');⚙️ setHeader($name, $value)
Устанавливает или переопределяет заголовок вручную.
$response = response()->setHeader('Cache-Control', 'no-store');🧩 withHeaders(array $headers)
Массовое добавление заголовков. Часто используется при форматировании ответа.
return response()
->json(['ok' => true])
->withHeaders([
'X-Request-ID' => uniqid(),
'X-Frame-Options' => 'DENY',
]);🔍 getHeaders()
Возвращает все заголовки, установленные в ответе:
$headers = response()->getHeaders();
print_r($headers);Пример вывода:
[
'Content-Type' => 'application/json; charset=utf-8',
'X-Powered-By' => 'PageBlocks',
]❌ removeHeader($name)
Удаляет заголовок, если он был установлен:
$response = response()->removeHeader('X-Powered-By');💾 Прикрепление данных к ответу
Для обычных (не-AJAX) запросов вы можете сохранить данные во флеш-сессию, чтобы использовать их в шаблонах после редиректа — например, передавать ошибки, старые значения форм и любые другие сообщения.
📎 with($key, $value, $name = '')
Сохраняет данные во флеш-сессию. Поддерживает именованные "группы" ($name) для разделения значений:
return response()
->back()
->with('success_message', 'Запись создана');С группой:
return response()
->back()
->with('message', 'Пользователь обновлён', 'admin');👜 withBag($name)
Позволяет задать группу по умолчанию, которую будут использовать все последующие вызовы with():
return response()
->withBag('form1')
->back()
->withErrors(['email' => 'Неверный формат'])
->withInput();Такой подход удобен, если вы хотите разделить данные по разным формам на странице.
🐞 withErrors(array $errors, $name = '')
Сохраняет ошибки в сессию. Если указано имя — ошибки попадут в соответствующую группу:
return response()->back()->withErrors([
'email' => 'Неверный формат',
'name' => 'Обязательное поле',
]);С группой:
return response()->back()->withErrors(['required' => 'Поле обязательно'], 'validation');🔁 withInput($name = '')
Сохраняет все введённые пользователем данные (request()->all()). Используется, чтобы восстановить значения после редиректа:
return response()
->back()
->withErrors($errors)
->withInput();С группой:
return response()->withInput('register_form');📋 Примеры в шаблоне
Без группы:
{$errors.email}
<input type="text" name="name" value="{$old_input.name}" />С группой register_form:
{$errors.register_form.email}
<input type="text" name="email" value="{$old_input.register_form.email}" />🔧 Низкоуровневые методы
Эти методы управляют основными параметрами ответа: содержимым и статусом. Обычно они используются внутри других методов (text, json, view и т.д.), но могут быть полезны для кастомных случаев или написания расширений.
📄 setContent($content = '')
Устанавливает «тело» ответа — строку, которая будет выведена пользователю:
return response()->setContent('<p>HTML напрямую</p>')->setStatusCode(200);📄 getContent()
Возвращает текущее содержимое ответа:
$content = response()->getContent();📊 setStatusCode($code, $text = '')
Устанавливает HTTP-статус-код и текст описания. Проверяет валидность кода:
return response()
->setStatusCode(403)
->setContent('Доступ запрещён');Если текст не указан — используется стандартный:
$response->setStatusCode(404); // "Not Found"📊 getStatusCode()
Возвращает установленный HTTP-код:
$code = response()->getStatusCode(); // например, 200📝 getStatusText()
Возвращает текстовую расшифровку статуса:
$text = response()->getStatusText(); // например, "OK"🚀 Отправка ответа
Все ответы завершаются методом:
📤 send()
Метод:
- записывает флеш-данные в
$_SESSION['pageblocks']['flash']; - устанавливает заголовки;
- выводит содержимое;
- завершает выполнение
exit.
Этот метод вызывается автоматически фреймворком, но если вы формируете ответ вручную — не забудьте вызвать send():
$response = response()->text('OK');
$response->send();🔚 Заключение
Класс Response — универсальный и гибкий компонент для контроллеров PageBlocks:
- 📄
text, 🌐html, 🔢json, 🧱object - 🖼️
view, 📥download - 🔁
redirect, 🔙back, 🛑abort - ✅
success, ❌error, ➕append - 🧾 Заголовки:
header(),setHeader(),withHeaders(),getHeaders(),removeHeader() - 💾 Флеш-данные:
with(),withErrors(),withInput() - 🔧 Низкоуровневое управление:
setContent(),setStatusCode(),getContent(),getStatusCode(),getStatusText() - 📤 Отправка:
send()
С этим инструментом ты легко покроешь любые сценарии: от простых редиректов до API-ответов и обработки ошибок.