Aktuálně: Postihly zákazy tvou profesi? Poptávka po ajťácích prudce roste, využij podzimní akce 30% výuky zdarma!
Pouze tento týden sleva až 80 % na e-learning týkající se JavaScript
JavaScript týden

Lekce 9 - Standardy jazyka PHP - PSR-7 (Rozhraní HTTP zpráv a proudů)

V předchozí lekci, Standardy jazyka PHP - PSR-7 (Obecná specifikace a proudy), jsme se začali věnovat standardu PSR-7, popsali si HTTP zprávy a proudy (streamy).

V lekci PSR-7 jsme se věnovali HTTP zprávám a proudům a dnes si ukážeme, jak bychom s nimi měli správně pracovat.

Psr\Http\Messa­ge\MessageInter­face

Pod pojmem HTTP zprávy obecně rozumíme požadavek klienta na server a odpověď serveru klientovi. Toto rozhraní definuje metody, které jsou společné oběma typům zpráv.

Zprávy jsou považovány za immutable objekty. Všechny metody, které mohou změnit stav požadavků nebo dotazů musí být implementovány tak, aby ponechaly původní znění a vrátily novou instanci se změněným stavem – NESMÍ tedy přepsat stav původní.

Tohoto rozhraní se také týkají standardy RFC 7230 a RFC 7231.

<?php
namespace Psr\Http\Message;

interface MessageInterface
{
    public function getProtocolVersion();
     /**
      * @return string
      */

Vrací verzi HTTP protokolu jako řetězec.

Řetězec MUSÍ obsahovat jenom číslo verze, například „1.1“ nebo „1.0“.

public function withProtocolVersion($version);
 /**
  * @param string $version
  * @return static
  */

Vrací instanci se zadanou verzí HTTP protokolu.

Řetězec MUSÍ obsahovat jenom číslo verze.

Tato funkce MUSÍ být implementována tak, aby zachovala nezměnitelnost (immutability) zprávy a MUSÍ vracet instanci s novou verzí protokolu.

/**
 *     // Reprezentuje hlavičku jako řetězec
 *     foreach ($message->getHeaders() as $name => $values) {
 *         echo $name . ': ' . implode(', ', $values);
 *     }
 *
 *     // Iterativně zobrazíme hlavičky
 *     foreach ($message->getHeaders() as $name => $values) {
 *         foreach ($values as $value) {
 *             header(sprintf('%s: %s', $name, $value), false);
 *         }
 *     }
 * @return string[][]
 */
public function getHeaders();

Vrací hodnoty všech hlaviček, kde klíče reprezentují názvy hlaviček a každá hodnota je pole řetězců spojených s hlavičkou.

Zatímco názvy hlaviček nejsou case-sensitive, funkce getHeaders() zachová původní zápis.

Každý klíč MUSÍ být názvem nějaké hlavičky a každá hodnota MUSÍ být pole řetězců dané hlavičky.

public function hasHeader($name);
/**
 * @param string $name
 * @return bool
 */
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Funkce hasHeader() zjistí, jestli se zadaný header ve zprávě vyskytuje. Argument je opět case-insensitive. Vrací hodnotu true, pokud alespoň nějaký header odpovídá argumentu; v opačném případě vrací hodnotu false.

public function getHeader($name);
/**
 * @param string $name
 * @return string[]
 */

Funkce getHeader() získá hodnotu headeru. Název zadáváme opět jako case-insensitive. Vrací pole (v podobě řetězce) pro zadaný název headeru.

Pokud se header ve zprávě nenachází, funkce MUSÍ vrátit prázdné pole.

public function getHeaderLine($name);
/**
 * @param string $name
 * @return string
 */

Funkce getHeaderLine() vrací všechny hodnoty (jednoho) headeru oddělené čárkou. Argument $name musí být zadáván jako case-insensitive.

Ale pozor! Ne všechny hlavičky mohou být tímto způsobem správně zřetězeny (např. Set-Cookie). V těchto případech použijme raději metodu getHeader() a při spojování pak i vlastní oddělovač. Pokud se ve zprávě hlavička nenachází, funkce MUSÍ vrátit prázdný string.

public function withHeader($name, $value);
/**
 * @param string $name
 * @param string|string[] $value // Nová hodnota
 * @return static
 * @throws \InvalidArgumentException
 *    // Výjimka pro neplatné argumenty (ať už hodnoty nebo názvy hlaviček)
 */

Vrací instanci se zadanou hodnotou nahrazující konkrétní header. I když jsou názvy hlaviček case-insensitive, velikost písmen bude touto funkcí zachována a může být vrácena pomocí getHeaders().

Funkce MUSÍ být implementována tak, aby zachovala nezměnitelnost zprávy a MUSÍ vrátit instanci s novou/aktuali­zovanou hodnotou.

public function withAddedHeader($name, $value);
/*
 * @param string $name Case-insensitive název
 * @param string|string[] $value
 *    // Hodnota (hodnoty), které chceme přidat
 * @return static
 * @throws \InvalidArgumentException
 *    // Vyhodí výjimku pro neplatný název/hodnoty
 */

Funkce withAddedHeader() vrací instanci určité hlavičky, ke které je přidána další hodnota. Existující hodnoty budou zachovány, nová bude přidána. Pokud header neexistoval, tak se vytvoří.

Funkce MUSÍ být implementována tak, aby zachovala nezměnitelnost zprávy a MUSÍ vrátit instanci s novou hodnotou/vytvořenou hlavičkou.

public function withoutHeader($name);
/*
 * @param string $name
 *   // Case-insensitive název hlavičky, kterou si přejeme odstranit
 * @return static
*/

Vrací instanci bez zadané hlavičky. Rozpoznávání názvů MUSÍ být nezávislé na velikosti písmen.

Funkce MUSÍ být implementována tak, aby zachovala nezměnitelnost zprávy a MUSÍ vrátit instanci bez zadané hlavičky.

public function getBody();
/*
 * @return StreamInterface
 */

Získá tělo zprávy a vrací ho jako stream.

    public function withBody(StreamInterface $body);
    /*
     * Tělo:
     * @param StreamInterface $body
     * @return static
     *  V případě neplatného těla vyhodí výjimku:
     * @throws \InvalidArgumentException
     */
}

Vrací instanci s předaným tělem zprávy. Tělo MUSÍ být StreamInterface objekt.

Funkce MUSÍ být implementována tak, aby zachovala nezměnitelnost zprávy a MUSÍ vrátit instanci, která obsahuje nový stream s tělem.

Psr\Http\Message\StreamInterface

Toto rozhraní popisuje datový proud a poskytuje wrapper pro nejběžnější operace, jakou je třeba serializace celého proudu do řetězce:

<?php
namespace Psr\Http\Message;

interface StreamInterface
{
    public function __toString();
    /**
     * @return string
     */

Funkce __toString() přečte všechna data z proudu od začátku do konce řetězce.

Funkce se MUSÍ pokusit o vyhledání začátku proudu předtím, než začne číst data a musí číst do té doby, než dojde na konec.

Pozor, použití této funkce může vyústit v uložení velkého množství dat do paměti.

Funkce NESMÍ vyhodit výjimku, pokud provádíme nějakou operaci s řetězci (viz php.net manuál).

public function close();
/**
 *
 * @return void
 */

public function detach();
/**
 *
 * @return resource|null
 * Vrátí zdroj, pokud existuje, jinak null
 */

Funkce close() uzavře proud a všechno s ním související. Druhá funkce oddělí od proudu jakékoliv zdroje s ním související. Po zavolání funkce je proud dále nepoužitelný.

Další funkce jsou poměrně jednoduché:

public function getSize();
/**
 *
 * @return int|null
 *  Vrátí velikost v bytech, pokud je známa, jinak null
 */

public function tell();
/**
 *
 * @return int // Pozice
 * @throws \RuntimeException
 *  Vyhodí výjimku při výskytu chyby
 */

public function eof();
/**
 *
 * @return bool
 */

Funkce getSize() získá velikost proudu, pokud je známa. Další funkce tell() vrací aktuální pozici ukazatele čtení nebo zápisu a funkce eof() vrací hodnotu true, pokud se nacházíme na konci proudu.

public function isSeekable();
/**
 * @return bool
 */

Funkce isSeekable() vrací hodnotu true nebo false podle toho, jestli je proud tzv. seekable. Pojem seekable znamená, že můžeme sami definovat pozici kurzoru v proudu, neboli přepsat či číst jakýkoliv byte. Pokud se pokusíme "hledat" mimo proud, respektive za ním, dojde k jeho prodloužení, tedy např. velikost souboru se zvětší.

public function seek($offset, $whence = SEEK_SET);
/**
 * @param int $offset
 * @param int $whence
 * @throws \RuntimeException
 */

Funkce seek() se posune na určenou pozici ve streamu. Parametr $whence určuje, jak bude vypočítána pozice kurzoru na základě offsetu.

Validní hodnoty jsou stejné jako pro známou vestavěnou funkci fseek():

  • SEEK_SET: Pozice je rovna offsetu (v bytech)
  • SEEK_CUR: Pozice je rovna offsetu + aktuální pozice
  • SEEK_END: Pozice je konec proudu + offset
public function rewind();
/**
 * @throws \RuntimeException
 */

Funkce rewind() přesune ukazatel na začátek proudu. Pokud proud není seekable, funkce vyhodí výjimku, jinak se provede seek(0) (viz funkce výše seek() a PHP manuál).

public function isWritable();
    /**
     * Určí, jestli do proudu můžeme zapisovat
     *
     * @return bool
     */

    public function write($string);
    /**
     * Zapíše data do proudu
     *
     * @param string $string Řetězec, který chceme zapsat
     * @return int Počet zapsaných bytů
     * @throws \RuntimeException
     */

    public function isReadable();
    /**
     * Určí, jestli je proud čitelný
     *
     * @return bool
     */

    public function read($length);
    /**
     * Přečte data ze streamu
     *
     * @param int $length
     *    Přečte až $length bytů z objektu a vrátí je
     * @return string
     *    Vrátí data nebo prázdný řetězec
     * @throws \RuntimeException
     */

    public function getContents();
    /**
     * Vrátí zbývající obsah ve streamu
     *
     * @return string
     * @throws \RuntimeException
     * Pokud nelze stream přečíst, vyhodí výjimku
     */

    public function getMetadata($key = null);
    /**
     * @param string $key Specific // Metadata
     * @return array|mixed|null
     */
}

Funkce getMetadata() získá metadata z proudu jako asociativní pole nebo vrátí specifický klíč. Tyto klíče jsou identické s těmi, které by vrátila funkce stream_get_meta_data(). Funkce vrací asociativní pole, jestliže neposkytneme žádný klíč. Jinak hodnotu přiřazenou klíči nebo hodnotu null, pokud klíč není nalezen.

V další lekci, Standardy jazyka PHP - PSR-7 (Request target a URI), se budeme věnovat další části PSR-7, a to request line, URI a superglobálním proměnným.


 

Předchozí článek
Standardy jazyka PHP - PSR-7 (Obecná specifikace a proudy)
Všechny články v sekci
Standardy jazyka PHP
Článek pro vás napsala Miroslava Škutová
Avatar
Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!
.
Aktivity (4)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!