HTTP request & response

HTTP požadavek a odpověď se zapouzdřuje do objektů Nette\Http\Request a Response, které nabízejí příjemnější API a fungují jako sanitizační filtr.

HTTP požadavek

Nette Framework pročistí data odeslané uživatelem od kontrolních a neplatných znaků. Zároveň odstraní případné magic_quotes.

HTTP požadavek, což je objekt třídy Nette\Http\Request, nevytváříme přímo, ale získáme jako službu z DI kontejneru.

Nette\Application\UI\Presenter má HTTP request k dispozici, získáme jej pomocí $httpRequest = $this->getHttpRequest().

URL požadavku získáme jako objekt Nette\Http\UrlScript:

$uri = $httpRequest->getUrl();
echo $uri; // např. https://doc.nette.org/cs/?action=edit
echo $uri->host; // nette.org

Zjištění HTTP metody, se kterou se na stránku přistoupilo:

echo $httpRequest->getMethod(); // GET, POST, HEAD, PUT

if ($httpRequest->isMethod('GET')) ...

Je spojení šifrované (HTTPS)?

echo $httpRequest->isSecured() ? 'ano' : 'ne';

Jde o AJAXový požadavek?

echo $httpRequest->isAjax() ? 'ano' : 'ne';

Jaká je IP adresa uživatele?

echo $httpRequest->getRemoteAddress(); // IP adresa uživatele
echo $httpRequest->getRemoteHost(); // a její DNS překlad

Z jaké URL uživatel přišel? Vrací se jako objekt Nette\Http\Url

echo $httpRequest->getReferer()->host;

Parametry požadavku:

$get = $httpRequest->getQuery(); // vrací pole všech parametrů z URL
$id = $httpRequest->getQuery('id'); // vrací GET parametr 'id' (nebo null)

$post = $httpRequest->getPost(); // vrací pole všech parametrů z POST
$id = $httpRequest->getPost('id'); // vrací POST parametr 'id' (nebo null)

$cookies = $httpRequest->getCookies(); // vrací všechny cookies
$sessId = $httpRequest->getCookie('sess_id'); // vrací cookie (nebo null)

Uploadované soubory jsou zapouzdřeny do objektů Nette\Http\FileUpload:

$files = $httpRequest->getFiles(); // vrací pole všech uploadů

$file = $httpRequest->getFile('avatar'); // vrací jeden soubor
echo $file->getName(); // jméno souboru odeslané uživatelem
echo $file->getSanitizedName(); // jméno bez nebezpečných znaků

HTTP hlavičky zjistíme:

// vrací asociativní pole HTTP hlaviček
$headers = $httpRequest->getHeaders();

// vrací konkrétní hlavičku (case-insensitive)
$userAgent = $httpRequest->getHeader('User-Agent');

Užitečná je metoda detectLanguage(), které předáme pole s jazyky, které aplikace podporuje, a ona vrátí ten, který by viděl návštěvníkův prohlížeč nejraději. Nejsou to žádná kouzla, jen se využívá hlavičky Accept-Language.

// prohlížeč odesílá např. Accept-Language: cs,en-us;q=0.8,en;q=0.5,sl;q=0.3

$langs = ['hu', 'pl', 'en']; // jazyky podporované aplikací

echo $httpRequest->detectLanguage($langs); // en

Tělo HTTP požadavku:

// ve výchozím stavu ekvivalent k: file_get_contents('php://input');
$body = $httpRequest->getRawBody();

RequestFactory a filtrování URL

Objekt s aktuálním HTTP požadavkem vyrábí Nette\Http\RequestFactory. Její chování můžeme pozměnit. Pomocí tzv. filtrů lze URL vyčistit od znaků, které se do nich mohou dostat kvůli špatně implementovaným komentářovým systémům na různých cizích webech:

$requestFactory = new Nette\Http\RequestFactory;

// odstraníme mezery z cesty
$requestFactory->urlFilters['path']['%20'] = '';

// odstraníme tečku, čárku nebo pravou závorku z konce URI
$requestFactory->urlFilters['url']['[.,)]$'] = '';

// vyčistíme cestu od zdvojených lomítek (výchozí filtr)
$requestFactory->urlFilters['path']['/{2,}'] = '/';

A poté si necháme vygenerovat nový httpRequest a uložíme jej do systémového kontejneru:

// $container je systémový kontejner
$container->addService('httpRequest', $requestFactory->createHttpRequest());

HTTP odpověď

HTTP odpověď, což je objekt třídy Nette\Http\Response, nevytváříme přímo, ale získáme jako službu z DI kontejneru.

Nette\Application\UI\Presenter má HTTP odpověď k dispozici, získáme ji pomocí $httpResponse = $this->getHttpResponse().

Zda je ještě možné odesílat hlavičky či měnit stavový kód, prozradí metoda isSent(). Pokud vrací true, nepůjde již žádnou další hlavičku či kód odeslat.

V takovém případě každý pokus o odeslání vyvolá výjimku Nette\InvalidStateException.

Stavový kód odpovědi odešleme nebo získáme takto:

$httpResponse->setCode(Nette\Http\Response::S404_NOT_FOUND);

echo $httpResponse->getCode(); // 404

Kvůli lepší srozumitelnosti zdrojového kódu doporučujeme pro kód používat místo čísla tyto předdefinované konstanty:

Http\IResponse::S200_OK
Http\IResponse::S204_NO_CONTENT
Http\IResponse::S300_MULTIPLE_CHOICES
Http\IResponse::S301_MOVED_PERMANENTLY
Http\IResponse::S302_FOUND
Http\IResponse::S303_SEE_OTHER
Http\IResponse::S303_POST_GET
Http\IResponse::S304_NOT_MODIFIED
Http\IResponse::S307_TEMPORARY_REDIRECT
Http\IResponse::S400_BAD_REQUEST
Http\IResponse::S401_UNAUTHORIZED
Http\IResponse::S403_FORBIDDEN
Http\IResponse::S404_NOT_FOUND
Http\IResponse::S410_GONE
Http\IResponse::S500_INTERNAL_SERVER_ERROR
Http\IResponse::S501_NOT_IMPLEMENTED
Http\IResponse::S503_SERVICE_UNAVAILABLE

Metoda setContentType($type, $charset=null) mění hlavičku Content-Type:

$httpResponse->setContentType('text/plain', 'UTF-8');

Přesměrování na jiné URL provede metoda redirect($url, $code=302). Nezapomeňte poté ukončit skript!

$httpResponse->redirect('http://example.com');
exit;

Pro nastavení expirace (vypršení platnosti) dokumentu použijeme metodu setExpiration(). Jejím parametrem je buď textový údaj, počet vteřin, nebo timestamp:

// cache prohlížeče vyprší za hodinu
$httpResponse->setExpiration('+ 1 hours');

HTTP hlavičku odešleme:

$httpResponse->setHeader('Pragma', 'no-cache');

// nebo chceme-li stejnou hlavičku odeslat vícekrát s různými hodnotami
$httpResponse->addHeader('Pragma', 'no-cache');

Odeslané HTTP hlavičky zjistíme přes:

// vrací asociativní pole HTTP hlaviček
$headers = $httpResponse->getHeaders();

// vrací konkrétní hlavičku (case-insensitive)
$pragma = $httpResponse->getHeader('Pragma');

Pro manipulaci s cookies slouží metody setCookie() a deleteCookie():

// setCookie($name, $value, $time, [$path, [$domain, [$secure, [$httpOnly])
$httpResponse->setCookie('lang', 'cs', '100 days'); // odešle cookie

// deleteCookie($name, [$path, [$domain, [$secure]]])
$httpResponse->deleteCookie('lang'); // smaže cookie

Tyto dvě metody přijímají ještě další parametry: $path (podadresář kde bude cookie dostupná), $domain a $secure. Jejich podrobný popis najdete u PHP funkce setcookie.