Відповіді

Flight допомагає генерувати частину заголовків відповіді для вас, але ви контролюєте більшість того, що надсилаєте назад користувачу. Іноді ви можете безпосередньо отримати доступ до об'єкта Response, але найчастіше ви будете використовувати екземпляр Flight для надсилання відповіді.

Відправка базової відповіді

Flight використовує ob_start(), щоб буферизувати вихід. Це означає, що ви можете використовувати echo або print для надсилання відповіді користувачу, і Flight захопить це та надішле назад користувачу з відповідними заголовками.


// Це надішле "Привіт, Світ!" у браузер користувача
Flight::route('/', function() {
    echo "Привіт, Світ!";
});

// HTTP/1.1 200 OK
// Content-Type: text/html
//
// Привіт, Світ!

Як альтернатива, ви можете викликати метод write(), щоб додати до тіла також.


// Це надішле "Привіт, Світ!" у браузер користувача
Flight::route('/', function() {
    // докладно, але іноді це необхідно
    Flight::response()->write("Привіт, Світ!");

    // якщо ви хочете отримати тіло, яке ви встановили на цьому етапі
    // ви можете зробити це так
    $body = Flight::response()->getBody();
});

Код статусу

Ви можете встановити код статусу відповіді, використовуючи метод status:

Flight::route('/@id', function($id) {
    if($id == 123) {
        Flight::response()->status(200);
        echo "Привіт, Світ!";
    } else {
        Flight::response()->status(403);
        echo "Заборонено";
    }
});

Якщо ви хочете отримати поточний код статусу, ви можете використовувати метод status без будь-яких аргументів:

Flight::response()->status(); // 200

Встановлення тіла відповіді

Ви можете встановити тіло відповіді, використовуючи метод write, однак, якщо ви виконуєте echo або print, це буде захоплено і надіслано як тіло відповіді через буферизацію виходу.

Flight::route('/', function() {
    Flight::response()->write("Привіт, Світ!");
});

// те саме, що й

Flight::route('/', function() {
    echo "Привіт, Світ!";
});

Очищення тіла відповіді

Якщо ви хочете очистити тіло відповіді, ви можете використовувати метод clearBody:

Flight::route('/', function() {
    if($someCondition) {
        Flight::response()->write("Привіт, Світ!");
    } else {
        Flight::response()->clearBody();
    }
});

Виконання зворотного виклику на тілі відповіді

Ви можете виконати зворотний виклик на тілі відповіді, використовуючи метод addResponseBodyCallback:

Flight::route('/users', function() {
    $db = Flight::db();
    $users = $db->fetchAll("SELECT * FROM users");
    Flight::render('users_table', ['users' => $users]);
});

// Це стисне всі відповіді для будь-якого маршруту
Flight::response()->addResponseBodyCallback(function($body) {
    return gzencode($body, 9);
});

Ви можете додати кілька зворотних викликів, і вони будуть виконані в порядку їх додавання. Оскільки це може приймати будь-який викликаємий, це може приймати масив класу [ $class, 'method' ], анонімну функцію $strReplace = function($body) { str_replace('hi', 'there', $body); };, або ім'я функції 'minify', якщо у вас є функція для мінімізації вашого HTML-коду, наприклад.

Примітка: Зворотні виклики маршрутів не працюватимуть, якщо ви використовуєте опцію налаштування flight.v2.output_buffering.

Зворотний виклик конкретного маршруту

Якщо ви хочете, щоб це застосовувалося тільки до конкретного маршруту, ви можете додати зворотний виклик безпосередньо в сам маршрут:

Flight::route('/users', function() {
    $db = Flight::db();
    $users = $db->fetchAll("SELECT * FROM users");
    Flight::render('users_table', ['users' => $users]);

    // Це стисне тільки відповідь для цього маршруту
    Flight::response()->addResponseBodyCallback(function($body) {
        return gzencode($body, 9);
    });
});

Опція Middleware

Ви також можете використовувати middleware, щоб застосувати зворотний виклик до всіх маршрутів через middleware:

// MinifyMiddleware.php
class MinifyMiddleware {
    public function before() {
        // Застосуйте зворотний виклик тут до об'єкта response().
        Flight::response()->addResponseBodyCallback(function($body) {
            return $this->minify($body);
        });
    }

    protected function minify(string $body): string {
        // мінімізуйте тіло якимось чином
        return $body;
    }
}

// index.php
Flight::group('/users', function() {
    Flight::route('', function() { /* ... */ });
    Flight::route('/@id', function($id) { /* ... */ });
}, [ new MinifyMiddleware() ]);

Встановлення заголовка відповіді

Ви можете встановити заголовок, такий як тип вмісту відповіді, використовуючи метод header:


// Це надішле "Привіт, Світ!" у браузер користувача у незакодованому тексті
Flight::route('/', function() {
    Flight::response()->header('Content-Type', 'text/plain');
    // або
    Flight::response()->setHeader('Content-Type', 'text/plain');
    echo "Привіт, Світ!";
});

JSON

Flight підтримує надсилання JSON і JSONP відповідей. Щоб надіслати JSON-відповідь, ви передаєте деякі дані для кодування в JSON:

Flight::json(['id' => 123]);

JSON з кодом статусу

Ви також можете передати код статусу як другий аргумент:

Flight::json(['id' => 123], 201);

JSON з красивим форматом

Ви також можете передати аргумент до останньої позиції для увімкнення красивого форматування:

Flight::json(['id' => 123], 200, true, 'utf-8', JSON_PRETTY_PRINT);

Якщо ви змінюєте параметри, передані в Flight::json(), і хочете спростити синтаксис, ви можете просто переназначити метод JSON:

Flight::map('json', function($data, $code = 200, $options = 0) {
    Flight::_json($data, $code, true, 'utf-8', $options);
}

// І тепер його можна використовувати так
Flight::json(['id' => 123], 200, JSON_PRETTY_PRINT);

JSON і зупинка виконання (v3.10.0)

Якщо ви хочете надіслати JSON-відповідь і зупинити виконання, ви можете використовувати метод jsonHalt. Це корисно для випадків, коли ви перевіряєте, можливо, якийсь вид авторизації, і якщо користувач не авторизований, ви можете надіслати JSON-відповідь негайно, очистити існуючий вміст тіла і зупинити виконання.

Flight::route('/users', function() {
    $authorized = someAuthorizationCheck();
    // Перевірте, чи користувач авторизований
    if($authorized === false) {
        Flight::jsonHalt(['error' => 'Неавторизований'], 401);
    }

    // Продовжте з рештою маршруту
});

Перед v3.10.0, вам доводилося робити щось подібне:

Flight::route('/users', function() {
    $authorized = someAuthorizationCheck();
    // Перевірте, чи користувач авторизований
    if($authorized === false) {
        Flight::halt(401, json_encode(['error' => 'Неавторизований']));
    }

    // Продовжте з рештою маршруту
});

JSONP

Для запитів JSONP ви можете опціонально передати ім'я параметра запиту, який ви використовуєте для визначення вашої функції зворотного виклику:

Flight::jsonp(['id' => 123], 'q');

Отже, коли ви здійснюєте GET-запит з використанням ?q=my_func, ви повинні отримати вихід:

my_func({"id":123});

Якщо ви не передасте ім'я параметра запиту, воно за замовчуванням буде jsonp.

Перенаправлення на іншу URL-адресу

Ви можете перенаправити поточний запит, використовуючи метод redirect() і передавши нову URL-адресу:

Flight::redirect('/new/location');

За замовчуванням Flight надсилає код статусу HTTP 303 ("Перейти за іншим"). Ви можете додатково встановити кастомний код:

Flight::redirect('/new/location', 401);

Зупинка

Ви можете зупинити фреймворк у будь-який момент, викликавши метод halt:

Flight::halt();

Ви також можете вказати необов'язковий код статусу HTTP і повідомлення:

Flight::halt(200, 'Бувайте...');

Виклик halt скине будь-який вміст відповіді до цього моменту. Якщо ви хочете зупинити фреймворк і вивести поточну відповідь, використовуйте метод stop:

Flight::stop();

Очищення даних відповіді

Ви можете очистити тіло відповіді та заголовки, використовуючи метод clear(). Це очистить будь-які заголовки, призначені відповіді, очистить тіло відповіді та встановить код статусу на 200.

Flight::response()->clear();

Очищення тільки тіла відповіді

Якщо ви хочете очистити тільки тіло відповіді, ви можете використовувати метод clearBody():

// Це все ще зберігатиме будь-які заголовки, встановлені на об'єкті response().
Flight::response()->clearBody();

HTTP кешування

Flight забезпечує вбудовану підтримку кешування на рівні HTTP. Якщо умови кешування виконуються, Flight поверне відповідь HTTP 304 Not Modified. Наступного разу, коли клієнт запросить той же ресурс, їх попросять використати свою локально кешовану версію.

Кешування на рівні маршруту

Якщо ви хочете кешувати всю вашу відповідь, ви можете використовувати метод cache() і передати час для кешування.


// Це кешуватиме відповідь на 5 хвилин
Flight::route('/news', function () {
  Flight::response()->cache(time() + 300);
  echo 'Цей вміст буде кешуватися.';
});

// Альтернативно, ви можете використовувати рядок, який ви передали б
// до методу strtotime()
Flight::route('/news', function () {
  Flight::response()->cache('+5 minutes');
  echo 'Цей вміст буде кешуватися.';
});

Остання модифікація

Ви можете використовувати метод lastModified і передати UNIX-ташку, щоб встановити дату і час останньої модифікації сторінки. Клієнт продовжить використовувати свій кеш, поки значення останньої модифікації не зміниться.

Flight::route('/news', function () {
  Flight::lastModified(1234567890);
  echo 'Цей вміст буде кешуватися.';
});

ETag

Кешування ETag схоже на Last-Modified, за винятком того, що ви можете вказати будь-який ідентифікатор, який ви бажаєте для ресурсу:

Flight::route('/news', function () {
  Flight::etag('my-unique-id');
  echo 'Цей вміст буде кешуватися.';
});

Пам'ятайте, що виклик будь-якого з методів lastModified або etag встановить і перевірить значення кешу. Якщо значення кешу однакове між запитами, Flight негайно надішле відповідь HTTP 304 і зупинить обробку.

Завантаження файлу (v3.12.0)

Існує допоміжний метод для завантаження файлу. Ви можете використовувати метод download і передати шлях.

Flight::route('/download', function () {
  Flight::download('/path/to/file.txt');
});