SyMfonAK - vyvíjame databázy pomocou frameworku Symfony

Symfony kontrolér (controller)

Z SyMfonAK
Prejsť na: navigácia, hľadanie

Symfony dokumentácia - hlavná stránkaSymfony kontrolér (controller)


Controller - original documentation

Je to funkcia php, ktorú vytvárame nato aby čítala informácie zo Symfony Request a aby vrátila Odpoveď (Response) alebo presmerovala. Dobré príklady na jednoduchý kontrolér sú v Symfony prvé stránky.


Jednoduchý kontrolér

Kontrolér je najčastejšie metóda v triede kontroléra (a method inside a controller class).


Základné triedy a servisy

Rozšírenie o AbstractController umožňuje prístup k rôznym pomocníkom (helper). Ako sú ..


Preklad do šablóny

$this->render();


Generovanie URL

$this->generateUrl().


Presmerovanie

$this->redirectToRoute() a redirect()


Načítanie služieb (fetching Services)

Symfony má veľá rôznych užitočných služieb, ktoré možno načítavať aj do kontroléra.

Napríklad logging:


use Psr\Log\LoggerInterface;
// ...

/**
 * @Route("/lucky/number/{max}")
 */
public function number($max, LoggerInterface $logger)
{
    $logger->info('We are logging!');
    // ...
}

Prehľad rôznych služieb (services) získame pomocou nasledujúceho príkazu na konzole:

php bin/console debug:autowiring


Pre služby máme možnosť spojiť ich napevno sa určitým argumentom. V kontroléri je možné vykonávať aj constructor injection.

Ďalšie podrobnosti o službách sa dočítate v Service Container.


Generovanie kontrolérov

Pre uľahčenie rutinnej práce slúži Symfony Maker. Pomocou príkazového riadka dialógom vytvoríme kontrolér alebo sadu súborov pre CRUD operácie (C - create, R - read, U - update, D - delete), základnú prácu s databázovou tabuľkou.


php bin/console make:controller BrandNewController

created: src/Controller/BrandNewController.php
created: templates/brandnew/index.html.twig



 php bin/console make:crud Product

created: src/Controller/ProductController.php
created: src/Form/ProductType.php
created: templates/product/_delete_form.html.twig
created: templates/product/_form.html.twig
created: templates/product/edit.html.twig
created: templates/product/index.html.twig
created: templates/product/new.html.twig
created: templates/product/show.html.twig


Správa chybových hlášok a stránok 404

Keď sa niečo nenájde, môžeme generovať chybu 404:

use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;

// ...
public function index()
{
    // retrieve the object from database
    $product = ...;
    if (!$product) {
        throw $this->createNotFoundException('The product does not exist');

V takom prípade si treba dať pozor, aby neostal v ostrom režime vývojový režim, viac v kapitole Symfony nastavenie (configuration). Chyba 404 by mohla byť príliš podrobná.

Inak ide chybová hlášku 505. Viac podrobností viď kapitolu Ako si prispôsobiť chybové hlásenia (How to Customize Error Pages).


Request objekt ako argument kontroléra

V prípade, že potrebujeme v prostredí kontroléra získať údaje o posielaných parametroch dotazu (query), získať hlavičku, prístup k nahrávanému súboru, získame ich z objektu Request.

Malý príklad:

use Symfony\Component\HttpFoundation\Request;

public function index(Request $request, $firstName, $lastName)
{
    $page = $request->query->get('page', 1);

    // ...
}

Nižšie, v ďalších sekciách tejto kapitoly sa dočítate ďalšie informácie.


Správa session premennej

Symfony má pekný objekt pre session premennej. Prednastavené je, že token je uložený v cookie a atribúty ukladá do súboru využitím php session.

Od verzie Symfony 3.3 je možné pristupovať k inštancii session a SessionInterface a má vlastnú stránku Session manažment.


use Symfony\Component\HttpFoundation\Session\SessionInterface;

public function indexAction(SessionInterface $session)
{
    // uložiť hodnotu pre neskoršie využitie
    $session->set('mojaPremenna', 'hodnota');

    // získať hodnotu attributu uloženú iným kontrolérom v inom request
    $aPom = $session->get('mojaPremenna');

    // využi prednastavenú hodnotu ak atribút neexistuje
    $filters = $session->get('filters', array());
}

Ďalšie podrobnosti môžete nájsť v Session.


Flash správy

Ide o nastavenie jednorázovej správy do session premennej.

Napríklad:

 $this->addFlash(
            'notice',
            'Your changes were saved!'
        );
        // $this->addFlash() is equivalent to $request->getSession()->getFlashBag()->add()

return $this->redirectToRoute(...);
    }

    return $this->render(...);
}


V nasledujúcej šablóne potom môžeme mať nastavené zobrazenie tejto správy, napríklad:

{# templates/base.html.twig #}

{# read and display just one flash message type #}
{% for message in app.flashes('notice') %}
    <div class="flash-notice">
        {{ message }}
    </div>
{% endfor %}

{# read and display several types of flash messages #}
{% for label, messages in app.flashes(['success', 'warning']) %}
    {% for message in messages %}
        <div class="flash-{{ label }}">
            {{ message }}
        </div>
    {% endfor %}
{% endfor %}

{# read and display all flash messages #}
{% for label, messages in app.flashes %}
    {% for message in messages %}
        <div class="flash-{{ label }}">
            {{ message }}
        </div>
    {% endfor %}
{% endfor %}{# templates/base.html.twig #}

{# read and display just one flash message type #}
{% for message in app.flashes('notice') %}
    <div class="flash-notice">
        {{ message }}
    </div>
{% endfor %}

{# read and display several types of flash messages #}
{% for label, messages in app.flashes(['success', 'warning']) %}
    {% for message in messages %}
        <div class="flash-{{ label }}">
            {{ message }}
        </div>
    {% endfor %}
{% endfor %}

{# read and display all flash messages #}
{% for label, messages in app.flashes %}
    {% for message in messages %}
        <div class="flash-{{ label }}">
            {{ message }}
        </div>
    {% endfor %}
{% endfor %}

Poznáme tri typy:

  • oznam (notice)
  • varovanie (warning)
  • chyba (error)

S flash správami súvisí metóda peek(), udrží ich spolu.

Objekty Request a Response

Ako už bolo vyššie spomenuté, v kontroléri môžeme pracovať s Requestom ale povinnosťou kontroléra je vrátiť Response objekt.

use Symfony\Component\HttpFoundation\Request;

public function index(Request $request)
{
    $request->isXmlHttpRequest(); // is it an Ajax request?

    $request->getPreferredLanguage(['en', 'fr']);

    // retrieves GET and POST variables respectively
    $request->query->get('page');
    $request->request->get('page');

    // retrieves SERVER variables
    $request->server->get('HTTP_HOST');

    // retrieves an instance of UploadedFile identified by foo
    $request->files->get('foo');

    // retrieves a COOKIE value
    $request->cookies->get('PHPSESSID');

    // retrieves an HTTP request header, with normalized, lowercase keys
    $request->headers->get('host');
    $request->headers->get('content-type');
}

Aj Response objekt má verejnú časť v hlavičke. Je objektom typu ResponseHeaderBag s množstvom metód na nastavenie alebo čítanie hlavičky. Názvy sú normalizované v zmysle že je jedno či napíšeme Content-Type, content-type alebo content_type.

Pri použití načítame takto:

use Symfony\Component\HttpFoundation\Response;

// creates a simple Response with a 200 status code (the default)
$response = new Response('Hello '.$name, Response::HTTP_OK);

// creates a CSS-response with a 200 status code
$response = new Response('<style> ... </style>');
$response->headers->set('Content-Type', 'text/css');

Viac informácií sa možno dočítať v Zložka HttpFoundation (The HttpFoundation Component).

Získanie prístupu ku konfiguračným nastaveniam

Prístup k hodnotám z konfiguračného nastavenia - na tento účel využijem helper $this->getParameter.

public function index()
{
    $contentsDir = $this->getParameter('kernel.project_dir').'/contents';
    // ...
}

Generovanie Response vo forme JSON

K tomuto účelu využijeme helper json() a vrátime JsonResponse objekt, ktorý údaje aj zakóduje.

public function index()
{
    // returns '{"username":"jane.doe"}' and sets the proper Content-Type header
    return $this->json(['username' => 'jane.doe']);

    // the shortcut defines three optional arguments
    // return $this->json($data, $status = 200, $headers = [], $context = []);
}

Ak máme spustený Prevodník (Serializer), tak on sa postará o serializáciu dát do JSON, inak bude použitá funkcia json_encode.

Streaming Response typu súbor (File)

Z prostrefia kontrolera vieme generovať odpoveď vo forme súboru, na to slúži pomocník file().

public function download()
{
    // send the file contents and force the browser to download it
    return $this->file('/path/to/some_file.pdf');
}

Pomocník file() má viacero možností nastavenia:

use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;

public function download()
{
    // load the file from the filesystem
    $file = new File('/path/to/some_file.pdf');

    return $this->file($file);

    // rename the downloaded file
    return $this->file($file, 'custom_name.pdf');

    // display the file contents in the browser instead of downloading it
    return $this->file('invoice_3241.pdf', 'my_invoice.pdf', ResponseHeaderBag::DISPOSITION_INLINE);
}


Myšlienky na záver

V tomto článku sme sa dozvedeli, že kontrolér je využívaný na získavanie požiadaviek (Request), generovanie odpovedí (Response). Ak je mapovaný na URL, tak jeho odpovede (Response) je možné vidieť.

Vývoj priniesol pre kontrolér rozšírenie - AbstractController. Prostredníctvom tohoto rozšírenia kontrolér získava prístup k nástrojom ako render(), redirectToRoute() a tiež na generovanie odpovedí typu CreateNotFoundException().

V ďalších článkoch sa naučíte ako nastaviť služby vo vnútri kontroléra, ktoré pomôžu ukladať dáta do databáz, získať dáta z databáz, vykonať uloženie zmenených údajov z formulárov a iné.

Poďme ďalej

Postúpte k téme preklad do šablón pomocou nástroja Twig - Symfony šablóny (templates).


Naučte sa viac o kontroléroch

starší článok k Symfony 3


<< Smerovanie ---------------------------------- >> Šablóny