HTTP Yanıtı
***********
.[perex]
Nette, HTTP yanıtını anlaşılır bir API'ye sahip nesnelerin içine alır.
HTTP yanıtı [api:Nette\Http\Response] nesnesiyle temsil edilir. Nette ile çalışıyorsanız bu nesne framework tarafından otomatik oluşturulur ve [bağımlılık enjeksiyonuyla |dependency-injection:passing-dependencies] size aktarılmasını sağlayabilirsiniz. Presenter'larda yalnızca `$this->getHttpResponse()` metodunu çağırın.
→ [Kurulum ve gereksinimler |@home#Kurulum]
Nette\Http\Response
===================
[Nette\Http\Request |request] nesnesinin aksine bu nesne değiştirilebilirdir, dolayısıyla durumu değiştirmek için (örneğin header göndermek için) setter'ları kullanabilirsiniz. Tüm setter'ların **herhangi bir gerçek çıktı gönderilmeden önce çağrılması gerektiğini** unutmayın. `isSent()` metodu, çıktının gönderilip gönderilmediğini gösterir. `true` döndürüyorsa, header gönderme girişimi `Nette\InvalidStateException` fırlatır.
setCode(int $code, ?string $reason=null) .[method]
--------------------------------------------------
[Yanıt durum kodunu |https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10] değiştirir. Kaynak kodun okunurluğu için, gerçek sayılar yerine [önceden tanımlı sabitleri |api:Nette\Http\IResponse] kullanmanız önerilir.
```php
$httpResponse->setCode(Nette\Http\Response::S404_NotFound);
```
getCode(): int .[method]
------------------------
Yanıtın durum kodunu döndürür.
isSent(): bool .[method]
------------------------
Header'ların sunucudan tarayıcıya gönderilip gönderilmediğini, yani artık header göndermenin ya da durum kodunu değiştirmenin olanaklı olup olmadığını döndürür.
setHeader(string $name, ?string $value) .[method]
-------------------------------------------------
Bir HTTP header'ı gönderir ve aynı adla daha önce gönderilmiş header'ın **üzerine yazar**. `$value` `null` ise header kaldırılır.
```php
$httpResponse->setHeader('Pragma', 'no-cache');
```
addHeader(string $name, string $value) .[method]
------------------------------------------------
Bir HTTP header'ı gönderir ve aynı adla daha önce gönderilmiş header'ın **üzerine yazmaz**.
```php
$httpResponse->addHeader('Accept', 'application/json');
$httpResponse->addHeader('Accept', 'application/xml');
```
deleteHeader(string $name) .[method]
------------------------------------
Daha önce gönderilmiş bir HTTP header'ını siler.
getHeader(string $header): ?string .[method]
--------------------------------------------
Gönderilen HTTP header'ını, yoksa `null` döndürür. Parametre büyük/küçük harfe duyarsızdır.
```php
$pragma = $httpResponse->getHeader('Pragma');
```
getHeaders(): array<string, string> .[method]
---------------------------------------------
Gönderilen tüm HTTP header'larını ilişkisel bir dizi olarak döndürür.
```php
$headers = $httpResponse->getHeaders();
echo $headers['Pragma'];
```
setContentType(string $type, ?string $charset=null) .[method]
-------------------------------------------------------------
`Content-Type` header'ını değiştirir.
```php
$httpResponse->setContentType('text/plain', 'UTF-8');
```
redirect(string $url, int $code=self::S302_Found): void .[method]
-----------------------------------------------------------------
Başka bir URL'ye yönlendirir. Ardından betiği sonlandırmayı unutmayın.
```php
$httpResponse->redirect('http://example.com');
exit;
```
setExpiration(?string $expire) .[method]
----------------------------------------
HTTP belgesinin son kullanma süresini `Cache-Control` ve `Expires` header'larıyla ayarlar. Parametre ya bir zaman aralığıdır (metin olarak) ya da önbelleklemeyi kapatan `null`.
```php
// tarayıcı önbelleği bir saat içinde dolar
$httpResponse->setExpiration('1 hour');
```
sendAsFile(string $fileName) .[method]
--------------------------------------
Yanıt, belirtilen adla bir *Farklı kaydet* iletişim kutusu üzerinden indirilir. Dosyanın kendisini göndermez.
```php
$httpResponse->sendAsFile('invoice.pdf');
```
setCookie(string $name, string $value, $expire, ?string $path=null, ?string $domain=null, ?bool $secure=null, ?bool $httpOnly=null, SameSite|string $sameSite='Lax', bool $partitioned=false) .[method]
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Bir çerez gönderir. Varsayılan parametre değerleri:
| `$path` | `'/'` | çerez, (alt) alan adı içindeki tüm yollarda kullanılabilir *(yapılandırılabilir)*
| `$domain` | `null` | yani geçerli (alt) alan adında kullanılabilir, ama onun alt alan adlarında değil *(yapılandırılabilir)*
| `$secure` | `auto` | site HTTPS üzerinde çalışıyorsa `true`, aksi hâlde `false` (framework varsayılanı; sınıfın kendi varsayılanı `false`) *(yapılandırılabilir)*
| `$httpOnly` | `true` | çerez JavaScript'ten erişilemez
| `$sameSite` | `'Lax'` | çerez, [kaynaklar arası erişimde |nette:glossary#SameSite çerezi] gönderilmeyebilir
| `$partitioned` | `false` | çerezin bölümlenip bölümlenmediği, aşağıya bakın *(v3.4'ten beri)*
`$path`, `$domain` ve `$secure` parametrelerinin varsayılan değerlerini [yapılandırmada |configuration#HTTP Çerezi] değiştirebilirsiniz.
Son kullanma; saniye sayısı olarak, metinsel bir aralık ya da tarih olarak veya bir `DateTimeInterface` nesnesi olarak verilir. `null` değeri, tarayıcının kapatıldığında attığı bir oturum çerezi oluşturur. Nette, son kullanmayı hem `Expires` hem de `Max-Age` niteliklerinde gönderir.
```php
$httpResponse->setCookie('lang', 'en', '100 days'); // 100 gün içinde dolar
$httpResponse->setCookie('lang', 'en', null); // oturum çerezi
```
`$domain` parametresi, çerezi hangi alan adlarının kabul edebileceğini belirler. Belirtilmezse çerez, onu ayarlayan aynı (alt) alan adı tarafından kabul edilir, ama onun alt alan adları tarafından edilmez. `$domain` belirtilirse alt alan adları da dahil olur. Bu yüzden `$domain` belirtmek, onu atlamaktan daha az kısıtlayıcıdır. Örneğin `$domain = 'nette.org'` ile çerezler `doc.nette.org` gibi tüm alt alan adlarında da kullanılabilir.
`$sameSite` değerini bir `Nette\Http\SameSite` enum'u olarak verebilirsiniz: `SameSite::Lax`, `SameSite::Strict` ya da `SameSite::None` (`'Lax'`, `'Strict'`, `'None'` dize değerleri de çalışır). Onu `SameSite::None` yaparsanız `$secure` niteliği otomatik açılır; çünkü tarayıcılar güvenli olmayan bir `SameSite=None` çerezini reddeder.
.{data-version:3.4.0}
Bölümlenmiş çerezler (CHIPS), bir çereze her üst düzey site için kendi ayrı deposunu verir. Böylece üçüncü taraf bir servis (örneğin gömülü bir widget) bölümlenmiş bir çerez ayarladığında, tarayıcı widget'ın göründüğü her site için ayrı bir kopya tutar ve bu kopyalar siteler arası izleme için birbirine bağlanamaz. Onu `$partitioned` değerini `true` yaparak açın; bu, `$secure` niteliğini de gerektirir, dolayısıyla otomatik açılır.
```php
$httpResponse->setCookie('theme', 'dark', '1 year', sameSite: SameSite::None, partitioned: true);
```
deleteCookie(string $name, ?string $path=null, ?string $domain=null, ?bool $secure=null): void .[method]
--------------------------------------------------------------------------------------------------------
Bir çerezi siler. Parametrelerin varsayılan değerleri:
- tüm dizinleri kapsayan `$path` (`'/'`)
- geçerli (alt) alan adını kapsayan, ama onun alt alan adlarını kapsamayan `$domain`
- `$secure`, [yapılandırmadaki |configuration#HTTP Çerezi] ayarlara bağlıdır
```php
$httpResponse->deleteCookie('lang');
```
Nette\Http\Context
==================
[api:Nette\Http\Context] nesnesi, isteği ve yanıtı bir araya getirir ve HTTP önbelleklemesine yardım eder. Servis olarak kaydedilmez, dolayısıyla onu kendiniz oluşturursunuz. Presenter'larda genellikle [lastModified() |application:presenters#HTTP önbelleklemesi] metodunu kullanmak daha kolaydır; context, yanıtı örneğin kendi yanıt sınıfınızdan kendiniz gönderdiğinizde işe yarar.
isModified(string|int|\DateTimeInterface|null $lastModified=null, ?string $etag=null): bool .[method]
-----------------------------------------------------------------------------------------------------
İçeriğin istemcinin son ziyaretinden bu yana değişip değişmediğini belirler. Son değiştirilme zamanını verirseniz `Last-Modified` header'ını gönderir; bir ETag doğrulayıcısı (içeriğin geçerli sürümünü tanımlayan kısa bir dize, örneğin hash'i) verirseniz `ETag` header'ını gönderir. Sonra ikisini de tarayıcının gönderdiği `If-Modified-Since` ve `If-None-Match` header'larıyla karşılaştırır.
Tarayıcıda zaten uyan bir sürüm varsa, metot `304 Not Modified` kodunu ayarlar ve `false` döndürür; o durumda yanıtın gövdesini hiç göndermeyin. Aksi hâlde `true` döndürür.
```php
public function send(Nette\Http\IRequest $request, Nette\Http\IResponse $response): void
{
$context = new Nette\Http\Context($request, $response);
if ($context->isModified(filemtime($this->file), md5_file($this->file))) {
readfile($this->file);
}
}
```
Her iki parametre de isteğe bağlıdır. İçeriğin değiştirilme zamanını bilmiyorsanız yalnızca ETag kullanın, tersi de geçerlidir.
HTTP Yanıtı
Nette, HTTP yanıtını anlaşılır bir API'ye sahip nesnelerin içine alır.
HTTP yanıtı Nette\Http\Response nesnesiyle temsil
edilir. Nette ile çalışıyorsanız bu nesne framework tarafından otomatik oluşturulur ve bağımlılık enjeksiyonuyla size aktarılmasını
sağlayabilirsiniz. Presenter'larda yalnızca $this->getHttpResponse() metodunu çağırın.
→ Kurulum ve gereksinimler
Nette\Http\Response
Nette\Http\Request nesnesinin aksine bu nesne değiştirilebilirdir,
dolayısıyla durumu değiştirmek için (örneğin header göndermek için) setter'ları kullanabilirsiniz. Tüm setter'ların
herhangi bir gerçek çıktı gönderilmeden önce çağrılması gerektiğini unutmayın. isSent() metodu,
çıktının gönderilip gönderilmediğini gösterir. true döndürüyorsa, header gönderme girişimi
Nette\InvalidStateException fırlatır.
setCode (int $code, ?string
$reason=null)
Yanıt durum kodunu değiştirir. Kaynak kodun
okunurluğu için, gerçek sayılar yerine önceden
tanımlı sabitleri kullanmanız önerilir.
$httpResponse->setCode(Nette\Http\Response::S404_NotFound);
getCode(): int
Yanıtın durum kodunu döndürür.
isSent(): bool
Header'ların sunucudan tarayıcıya gönderilip gönderilmediğini, yani artık header göndermenin ya da durum kodunu
değiştirmenin olanaklı olup olmadığını döndürür.
Bir HTTP header'ı gönderir ve aynı adla daha önce gönderilmiş header'ın üzerine yazar. $value
null ise header kaldırılır.
$httpResponse->setHeader('Pragma', 'no-cache');
Bir HTTP header'ı gönderir ve aynı adla daha önce gönderilmiş header'ın üzerine yazmaz.
$httpResponse->addHeader('Accept', 'application/json');
$httpResponse->addHeader('Accept', 'application/xml');
Daha önce gönderilmiş bir HTTP header'ını siler.
Gönderilen HTTP header'ını, yoksa null döndürür. Parametre büyük/küçük harfe duyarsızdır.
$pragma = $httpResponse->getHeader('Pragma');
Gönderilen tüm HTTP header'larını ilişkisel bir dizi olarak döndürür.
$headers = $httpResponse->getHeaders();
echo $headers['Pragma'];
setContentType (string $type, ?string
$charset=null)
Content-Type header'ını değiştirir.
$httpResponse->setContentType('text/plain', 'UTF-8');
redirect (string $url, int
$code=self::S302_Found): void
Başka bir URL'ye yönlendirir. Ardından betiği sonlandırmayı unutmayın.
$httpResponse->redirect('http://example.com');
exit;
setExpiration (?string $expire)
HTTP belgesinin son kullanma süresini Cache-Control ve Expires header'larıyla ayarlar. Parametre ya
bir zaman aralığıdır (metin olarak) ya da önbelleklemeyi kapatan null.
// tarayıcı önbelleği bir saat içinde dolar
$httpResponse->setExpiration('1 hour');
sendAsFile (string $fileName)
Yanıt, belirtilen adla bir Farklı kaydet iletişim kutusu üzerinden indirilir. Dosyanın kendisini göndermez.
$httpResponse->sendAsFile('invoice.pdf');
setCookie (string $name, string $value,
$expire, ?string $path=null, ?string $domain=null, ?bool $secure=null, ?bool $httpOnly=null,
SameSite|string $sameSite='Lax', bool $partitioned=false)
Bir çerez gönderir. Varsayılan parametre değerleri:
$path |
'/' |
çerez, (alt) alan adı içindeki tüm yollarda kullanılabilir (yapılandırılabilir) |
$domain |
null |
yani geçerli (alt) alan adında kullanılabilir, ama onun alt alan adlarında değil (yapılandırılabilir) |
$secure |
auto |
site HTTPS üzerinde çalışıyorsa true, aksi hâlde false (framework varsayılanı; sınıfın
kendi varsayılanı false) (yapılandırılabilir) |
$httpOnly |
true |
çerez JavaScript'ten erişilemez |
$sameSite |
'Lax' |
çerez, kaynaklar arası erişimde gönderilmeyebilir |
$partitioned |
false |
çerezin bölümlenip bölümlenmediği, aşağıya bakın (v3.4'ten beri) |
$path, $domain ve $secure parametrelerinin varsayılan değerlerini yapılandırmada değiştirebilirsiniz.
Son kullanma; saniye sayısı olarak, metinsel bir aralık ya da tarih olarak veya bir DateTimeInterface nesnesi
olarak verilir. null değeri, tarayıcının kapatıldığında attığı bir oturum çerezi oluşturur. Nette, son
kullanmayı hem Expires hem de Max-Age niteliklerinde gönderir.
$httpResponse->setCookie('lang', 'en', '100 days'); // 100 gün içinde dolar
$httpResponse->setCookie('lang', 'en', null); // oturum çerezi
$domain parametresi, çerezi hangi alan adlarının kabul edebileceğini belirler. Belirtilmezse çerez, onu
ayarlayan aynı (alt) alan adı tarafından kabul edilir, ama onun alt alan adları tarafından edilmez. $domain
belirtilirse alt alan adları da dahil olur. Bu yüzden $domain belirtmek, onu atlamaktan daha az
kısıtlayıcıdır. Örneğin $domain = 'nette.org' ile çerezler doc.nette.org gibi tüm alt alan
adlarında da kullanılabilir.
$sameSite değerini bir Nette\Http\SameSite enum'u olarak verebilirsiniz:
SameSite::Lax, SameSite::Strict ya da SameSite::None ('Lax',
'Strict', 'None' dize değerleri de çalışır). Onu SameSite::None yaparsanız
$secure niteliği otomatik açılır; çünkü tarayıcılar güvenli olmayan bir SameSite=None
çerezini reddeder.
Bölümlenmiş çerezler (CHIPS), bir çereze her üst düzey site için kendi ayrı deposunu verir.
Böylece üçüncü taraf bir servis (örneğin gömülü bir widget) bölümlenmiş bir çerez ayarladığında, tarayıcı
widget'ın göründüğü her site için ayrı bir kopya tutar ve bu kopyalar siteler arası izleme için birbirine bağlanamaz.
Onu $partitioned değerini true yaparak açın; bu, $secure niteliğini de gerektirir,
dolayısıyla otomatik açılır.
$httpResponse->setCookie('theme', 'dark', '1 year', sameSite: SameSite::None, partitioned: true);
deleteCookie (string $name, ?string
$path=null, ?string $domain=null, ?bool $secure=null): void
Bir çerezi siler. Parametrelerin varsayılan değerleri:
- tüm dizinleri kapsayan
$path ('/')
- geçerli (alt) alan adını kapsayan, ama onun alt alan adlarını kapsamayan
$domain
$secure, yapılandırmadaki ayarlara
bağlıdır
$httpResponse->deleteCookie('lang');
Nette\Http\Context
Nette\Http\Context nesnesi, isteği ve yanıtı bir
araya getirir ve HTTP önbelleklemesine yardım eder. Servis olarak kaydedilmez, dolayısıyla onu kendiniz oluşturursunuz.
Presenter'larda genellikle lastModified()
metodunu kullanmak daha kolaydır; context, yanıtı örneğin kendi yanıt sınıfınızdan kendiniz gönderdiğinizde
işe yarar.
isModified (string|int|\DateTimeInterface|null
$lastModified=null, ?string $etag=null): bool
İçeriğin istemcinin son ziyaretinden bu yana değişip değişmediğini belirler. Son değiştirilme zamanını verirseniz
Last-Modified header'ını gönderir; bir ETag doğrulayıcısı (içeriğin geçerli sürümünü tanımlayan kısa
bir dize, örneğin hash'i) verirseniz ETag header'ını gönderir. Sonra ikisini de tarayıcının gönderdiği
If-Modified-Since ve If-None-Match header'larıyla karşılaştırır.
Tarayıcıda zaten uyan bir sürüm varsa, metot 304 Not Modified kodunu ayarlar ve false
döndürür; o durumda yanıtın gövdesini hiç göndermeyin. Aksi hâlde true döndürür.
public function send(Nette\Http\IRequest $request, Nette\Http\IResponse $response): void
{
$context = new Nette\Http\Context($request, $response);
if ($context->isModified(filemtime($this->file), md5_file($this->file))) {
readfile($this->file);
}
}
Her iki parametre de isteğe bağlıdır. İçeriğin değiştirilme zamanını bilmiyorsanız yalnızca ETag kullanın, tersi
de geçerlidir.