Путеводитель Symfony: Компонент HTTPKernel

  • 1 год назад

В этом руководстве мы рассмотрим основные компоненты, с помощью которых создаются приложения:

  • HTTP Kenel и HTTP Foundation
  • Диспетчер событий
  • Маршрутизация и YAML
  • Внедрение зависимости
  • Консоль

HTTPKernel

Symfony предоставляет компопонет HttpKernel который реализует протокол HTTP: он конвертирует Request в Response.

Все вращается вокруг следующего интерфейса:

<?php

namespace Symfony\Component\HttpKernel;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

interface HttpKernelInterface
{
    const MASTER_REQUEST = 1;
    const SUB_REQUEST = 2;

    /**
     * @param Request $request
     * @param int     $type
     * @param bool    $catch   Whether to catch exceptions or not
     *
     * @return Response
     */
    public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
}

HttpFoundation

HttpKernel базируется на компоненте HttpFoundation, который обеспечивает:

  • Request: упаковывает $_GET, $_POST, $_COOKIE, $_FILES и $_SERVER
  • Response: упаковывает header() и setcookie(), но также отображает контент

Примечание: Недостаток глобальных переменных состоит в том, что к ним могут получить доступ множество функций, что определяет непредсказуемость их состояния (вследствие этого случаются ошибки, которые сложно найти/понять). С компонентом HttpFoundation, доступ к суперглобальным переменным PHP не прямой, а через объекты, которые упаковывают их (напр., Request) (эти объекты не глобальные).

Вот типичный пример использования:

$request = Request::createFromGlobals();
$response = $httpKernel->handle($request);
$reponse->send();

В приведенном выше примере объект Request будет инициализирован при помощи суперглобальных переменных PHP. Иногда полезно сделать это с использованием своих собственных значений (например, для тестов):

$uri = '/v1/items';
$method = 'POST';
$parameters = array(); // GET or POST parameters, usually left unused (use uri and content instead)
$cookies = array();
$files = array();
$headers = array('CONTENT_TYPE' => 'application/json');
$content = json_encode(array('name' => 'Arthur Dent'));

$request = Request::create($uri, $method, $getOrPostParameters, $cookies, $files, $headers, $content);

В нашем приложении мы будем преимущественно извлекать его параметры:

$getParameter = $request->query->get('description'); // e.g. from URI `/?description=hitchhicker`
$postParameter = $request->request->get('name'); // e.g. from content `name=Arthur`
$header = $request->headers->get('Content-Type'); // e.g. from headers `Content-Type: application/x-www-form-urlencoded`

$customParameter = $request->attributes->get('_route');

Примечание: Эти публичные свойства являются экземплярами Symfony\Component\HttpFoundation\ParameterBag, за исключением headers, который является экземпляром Symfony\Component\HttpFoundation\HeaderBag.

В нашем приложении мы будем, главным образом, создавать Response:

$content = json_encode(array('name' => 'Arthur Dent'));
$status = 201;
$headers = array('Content-Type' => 'application/json');
$response = new Reponse($content, $status, $headers);

Пример

Давайте создадим небольшой пример Hello World:

<?php

use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class HelloWorldHttpKernel implements HttpKernelInterface
{
    public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
    {
        $name = $request->query->get('name', 'World');

        return new Response("Hello $name!", 200);
    }
}

$httpKernel = new HelloWorldHttpKernel();
$request = Request::createFromGlobals();
$response = $httpKernel->handle($request);
$response->send();

Получим следующее:

  • Для URL / мы получаем Hello World!
  • Для URL /?name=Arthur мы получаем Hello Arthur!

Заключение

Symfony предлагает простой, но при этом полезный компонент, который позволяет нам следовать протоколу HTTP.

В этой статье мы рассмотрели основные моменты работы этого компонента, но на практике нам необязательно создавать нашу собственную реализацию HttpKernelInterface.

Использование готового абстрактного класса Symfony\Component\HttpKernel\Kernel дает нам доступ к ряду функций, которые мы рассмотрим в следующих статьях:

  • Диспетчер событий
  • Маршрутизация и YAML
  • Внедрение зависимости.

Комментарии

0