HTTP İsteği

Nette, HTTP isteğini anlaşılır bir API'ye sahip nesnelerin içine alır ve bunu yaparken bir temizleme filtresi de sunar.

HTTP isteği Nette\Http\Request 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->getHttpRequest() metodunu çağırın. Nette Framework'ün dışında çalışıyorsanız nesneyi RequestFactory ile oluşturabilirsiniz.

Nette'in büyük bir üstünlüğü, nesneyi oluştururken tüm girdi parametrelerini (GET, POST, COOKIE) ve URL'yi otomatik olarak temizlemesi, denetim karakterlerini ve geçersiz UTF-8 dizilerini kaldırmasıdır. Bu veriyle sonra güvenle çalışabilirsiniz. Temizlenen veri ardından presenter'larda ve formlarda kullanılır.

Kurulum ve gereksinimler

Nette\Http\Request

Bu nesne değişmezdir. Setter'ı yoktur; yalnızca bir wither'ı, withUrl(), vardır; bu metot nesneyi değiştirmez, değiştirilmiş değere sahip yeni bir örnek döndürür.

withUrl (Nette\Http\UrlScript $url): Nette\Http\Request

Farklı bir URL'ye sahip bir klon döndürür.

getUrl(): Nette\Http\UrlScript

İsteğin URL'sini bir UrlScript nesnesi olarak döndürür.

$url = $httpRequest->getUrl();
echo $url; // https://nette.org/en/documentation?action=edit
echo $url->getHost(); // nette.org

Uyarı: Tarayıcılar fragment'ı sunucuya göndermez, dolayısıyla $url->getFragment() boş bir dize döndürür.

getQuery (?string $key=null): string|array|null

GET isteği parametrelerini döndürür.

$all = $httpRequest->getQuery();    // tüm URL parametrelerinin dizisi
$id = $httpRequest->getQuery('id'); // 'id' GET parametresini döndürür (ya da null)

getPost (?string $key=null): string|array|null

POST isteği parametrelerini döndürür.

$all = $httpRequest->getPost();     // tüm POST parametrelerinin dizisi
$id = $httpRequest->getPost('id');  // 'id' POST parametresini döndürür (ya da null)

getFile (string|string[] $key): ?Nette\Http\FileUpload

Bir yüklemeyi Nette\Http\FileUpload nesnesi olarak döndürür:

$file = $httpRequest->getFile('avatar');
if ($file?->hasFile()) { // herhangi bir dosya yüklendi mi?
	$file->getUntrustedName(); // kullanıcının gönderdiği dosya adı
	$file->getSanitizedName(); // tehlikeli karakterler olmadan ad
}

İç içe bir yapıya erişmek için bir anahtar dizisi verin.

// <input type="file" name="my-form[details][avatar]">
$file = $request->getFile(['my-form', 'details', 'avatar']);

Dış veriye güvenemeyeceğiniz ve dolayısıyla dosyaların yapısına dayanamayacağınız için, bu yaklaşım örneğin başarısız olabilecek $request->getFiles()['my-form']['details']['avatar'] ifadesinden daha güvenlidir.

getFiles(): array

Tüm yüklemelerin normalleştirilmiş bir yapıdaki ağacını döndürür; yapraklar Nette\Http\FileUpload nesneleridir:

$files = $httpRequest->getFiles();

getCookie (string $key): ?string

Bir çerezi ya da yoksa null döndürür.

$sessId = $httpRequest->getCookie('sess_id');

getCookies(): array

Tüm çerezleri döndürür.

$cookies = $httpRequest->getCookies();

getMethod(): string

İstek için kullanılan HTTP metodunu döndürür.

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

isMethod (string $method)bool

İstek için kullanılan HTTP metodunu sınar. Parametre büyük/küçük harfe duyarsızdır.

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

getHeader (string $header): ?string

Bir HTTP header'ını ya da yoksa null döndürür. Parametre büyük/küçük harfe duyarsızdır.

$userAgent = $httpRequest->getHeader('User-Agent');

getHeaders(): array<string, string>

Tüm HTTP header'larını ilişkisel bir dizi olarak döndürür. Anahtarlar küçük harfe normalleştirilir.

$headers = $httpRequest->getHeaders();
echo $headers['content-type'];

isSecured(): bool

Bağlantı şifreli mi (HTTPS)? Düzgün çalışması proxy kurulumunu gerektirebilir.

isSameSite(): bool

İstek aynı siteden mi geldi? 3.4 sürümünden beri yerini daha yetenekli isFrom() aldı.

isFrom (FetchSite|array $site, FetchDest|array|null $dest=null, ?bool $user=null)bool

İsteğin nereden geldiğini ve tarayıcının onu nasıl yaptığını, tarayıcının kendisinin ayarladığı ve kurbanın tarayıcısında çalışan bir sayfanın ne taklit edebildiği ne de kaldırabildiği Sec-Fetch-* header'larına (Fetch Metadata denir) dayanarak söyler. Nette bunu, formları ve sinyalleri Cross-Site Request Forgery (CSRF) saldırılarına karşı otomatik korumak için içeride kullanır. Kendi hassas eylemlerinizi, örneğin API uçlarını ya da yıkıcı bağlantıları korumak istediğinizde işe yarar.

Metot, yalnızca istek verdiğiniz tüm koşullara uyduğunda true döndürür. İlk parametre $site, isteği başlatan sayfa ile sitenizin arasındaki ilişkiyi anlatır (Sec-Fetch-Site header'ı). Tek bir değer ya da şu FetchSite durumlarından oluşan bir liste kabul eder:

  • FetchSite::SameOrigin – tam olarak aynı kaynaktan (şema, host ve port)
  • FetchSite::SameSite – aynı siteden, belki farklı bir alt alan adından
  • FetchSite::CrossSite – yabancı bir siteden
  • FetchSite::None – kullanıcı onu doğrudan başlattı, örneğin URL'yi yazarak ya da bir yer imini açarak
// istek kendi sayfalarımızdan mı geldi?
if (!$httpRequest->isFrom([FetchSite::SameOrigin, FetchSite::SameSite])) {
	// eylemi engelle
}

İsteğe bağlı $dest parametresi (Sec-Fetch-Dest header'ı), tarayıcının ne tür bir kaynak getirdiğini söyler; örneğin üst düzey bir gezinme için FetchDest::Document, JavaScript'ten yapılan bir istek için FetchDest::Empty. İsteğe bağlı $user parametresi (Sec-Fetch-User header'ı), gezinmenin bir bağlantıya tıklamak ya da form göndermek gibi gerçek bir kullanıcı eylemiyle tetiklenip tetiklenmediğini gösterir; bunu zorunlu kılmak için true verin.

Bir eylemin yalnızca kendi sayfalarınızdan ve yalnızca gerçek bir kullanıcı eylemiyle erişilebilir olduğunun denetimi o zaman şöyle görünür:

if (!$httpRequest->isFrom(FetchSite::SameOrigin, FetchDest::Document, user: true)) {
	$this->error();
}

Eski tarayıcılar (16.4 öncesi Safari) Sec-Fetch-* header'larını göndermez. Onlar için Nette, isteğin yalnızca siteler arası olmadığını kanıtlayan bir SameSite=Strict çerezine geri düşer. Ek olarak $dest ya da $user gerektiren bir denetim bu yolla doğrulanamaz ve o tarayıcılarda false döndürür; bu fazla katıysa yalnızca $site değerini sınayın.

isAjax(): bool

Bu bir AJAX isteği mi?

getRemoteAddress(): ?string

Kullanıcının IP adresini döndürür. Düzgün çalışması proxy kurulumunu gerektirebilir.

getRemoteHost(): ?string

Kullanımdan kaldırıldı, her zaman null döndürür. Ters DNS sorguları yavaş ve güvenilmezdi; host adına ihtiyacınız varsa onu getRemoteAddress() değerinden kendiniz çözün.

getBasicCredentials(): ?array

Basic HTTP authentication için kimlik doğrulama bilgilerini döndürür.

[$user, $password] = $httpRequest->getBasicCredentials();

getRawBody(): ?string

HTTP isteğinin gövdesini döndürür.

$body = $httpRequest->getRawBody();

getOrigin(): ?UrlImmutable

İsteğin geldiği kaynağı döndürür. Bir kaynak; şema (protokol), host adı ve porttan oluşur; örneğin https://example.com:8080. Origin header'ı yoksa ya da 'null' olarak ayarlıysa null döndürür.

$origin = $httpRequest->getOrigin();
echo $origin; // https://example.com:8080
echo $origin?->getHost(); // example.com

Tarayıcı Origin header'ını şu durumlarda gönderir:

  • Kaynaklar arası istekler (farklı bir alan adına yapılan AJAX çağrıları)
  • POST, PUT, DELETE ve diğer değiştirici istekler
  • Fetch API ile yapılan istekler

Tarayıcı Origin header'ını şunlarda GÖNDERMEZ:

  • Aynı alan adına yapılan sıradan GET istekleri (aynı kaynakta gezinme)
  • Adres çubuğuna URL yazarak doğrudan gezinme
  • Tarayıcı olmayan istemcilerden gelen istekler

Referer header'ının aksine Origin yalnızca şemayı, host'u ve portu içerir; URL yolunun tamamını değil. Bu, kullanıcı gizliliğini korurken onu güvenlik denetimleri için daha uygun kılar. Origin header'ı öncelikle CORS (Cross-Origin Resource Sharing) doğrulamasında kullanılır.

detectLanguage (array $langs): ?string

Dili saptar. $langs parametresi olarak uygulamanın desteklediği dillerden oluşan bir dizi verin; metot, ziyaretçinin tarayıcısının yeğlediği dili döndürür. Sihir değil; yalnızca Accept-Language header'ını kullanır. Eşleşme bulunmazsa null döndürür.

// Tarayıcı örneğin şunu gönderir: Accept-Language: cs,en-us;q=0.8,en;q=0.5,sl;q=0.3

$langs = ['hu', 'pl', 'en']; // uygulamanın desteklediği diller
echo $httpRequest->detectLanguage($langs); // en

RequestFactory

Nette\Http\RequestFactory sınıfı, geçerli HTTP isteğini temsil eden bir Nette\Http\Request örneği oluşturmak için kullanılır. (Nette ile çalışıyorsanız HTTP istek nesnesi framework tarafından otomatik oluşturulur.)

$factory = new Nette\Http\RequestFactory;
$httpRequest = $factory->fromGlobals();

fromGlobals() metodu, istek nesnesini geçerli PHP genel değişkenlerine ($_GET, $_POST, $_COOKIE, $_FILES ve $_SERVER) dayanarak oluşturur. Nesneyi oluştururken tüm girdi parametrelerini (GET, POST, COOKIE) ve URL'yi denetim karakterlerinden ve geçersiz UTF-8 dizilerinden otomatik olarak temizler; böylece bu veriyle sonradan çalışırken güvenlik sağlanır.

RequestFactory, fromGlobals() çağrılmadan önce yapılandırılabilir:

  • $factory->setBinary() metodu, girdi parametrelerinin denetim karakterlerinden ve geçersiz UTF-8 dizilerinden otomatik temizlenmesini kapatır.
  • $factory->setProxy(...) metodu, kullanıcının IP adresinin doğru saptanması için gereken proxy sunucusunun IP adresini belirtir.
  • $factory->setForceHttps() .{data-version:3.3.4} metodu, sunucu ortamından bağımsız olarak isteğin şemasını HTTPS'e zorlar.

RequestFactory, URL isteğinin parçalarını otomatik dönüştüren filtreler tanımlamaya olanak tanır. Bu filtreler, örneğin çeşitli web sitelerindeki yorum sistemlerinin hatalı gerçekleştirimleri tarafından eklenmiş olabilecek istenmeyen karakterleri URL'lerden kaldırır:

// yoldan boşlukları kaldır
$requestFactory->urlFilters['path']['%20'] = '';

// URI'nin sonundaki noktayı, virgülü ya da sağ parantezi kaldır
$requestFactory->urlFilters['url']['[.,)]$'] = '';

// yolu çift eğik çizgilerden temizle (varsayılan filtre)
$requestFactory->urlFilters['path']['/{2,}'] = '/';

İlk anahtar, 'path' ya da 'url', filtrenin URL'nin hangi parçasına uygulanacağını belirler. İkinci anahtar aranacak düzenli ifade, değer ise bulunan metnin yerine konacak değiştirmedir.

Yüklenen Dosyalar

Nette\Http\Request::getFiles() metodu, tüm yüklemeleri normalleştirilmiş bir yapıda döndürür; yapraklar Nette\Http\FileUpload nesneleridir. Bunlar, <input type=file> form elemanının gönderdiği veriyi içine alır.

Yapı, HTML'deki eleman adlandırmasını yansıtır. En basit durumda bu, şöyle gönderilen tek ve adlandırılmış bir form elemanı olabilir:

<input type="file" name="avatar">

Bu durumda $request->getFiles() şu diziyi döndürür:

[
	'avatar' => /* FileUpload örneği */
]

FileUpload nesnesi, kullanıcı hiç dosya yüklemese ya da yükleme başarısız olsa bile oluşturulur. Bir dosya gönderildiyse hasFile() metodu true döndürür:

$request->getFile('avatar')?->hasFile();

Dizi yazımı kullanan bir eleman adı söz konusu olduğunda:

<input type="file" name="my-form[details][avatar]">

döndürülen ağaç şöyle görünür:

[
	'my-form' => [
		'details' => [
			'avatar' => /* FileUpload örneği */
		],
	],
]

Dosya dizileri de oluşturabilirsiniz:

<input type="file" name="my-form[details][avatars][]" multiple>

Böyle bir durumda yapı şöyle görünür:

[
	'my-form' => [
		'details' => [
			'avatars' => [
				0 => /* FileUpload örneği */,
				1 => /* FileUpload örneği */,
				2 => /* FileUpload örneği */,
			],
		],
	],
]

İç içe dizinin 1 numaralı indeksine erişmenin en iyi yolu şudur:

$file = $request->getFile(['my-form', 'details', 'avatars', 1]);
if ($file instanceof Nette\Http\FileUpload) {
	// ...
}

Dış veriye güvenemeyeceğiniz ve dolayısıyla dosyaların yapısına dayanamayacağınız için, bu yaklaşım örneğin başarısız olabilecek $request->getFiles()['my-form']['details']['avatars'][1] ifadesinden daha güvenlidir.

FileUpload Metotlarına Genel Bakış

hasFile(): bool

Kullanıcı bir dosya yüklediyse true döndürür.

isOk(): bool

Dosya başarıyla yüklendiyse true döndürür.

getError(): int

Yüklenen dosyayla ilişkili hata kodunu döndürür. UPLOAD_ERR_XXX sabitlerinden biridir. Dosya başarıyla yüklendiyse UPLOAD_ERR_OK döndürür.

move (string $dest)

Yüklenen dosyayı yeni bir konuma taşır. Hedef dosya zaten varsa üzerine yazılır.

$file->move('/path/to/files/name.ext');

getContents(): ?string

Yüklenen dosyanın içeriğini döndürür. Yükleme başarılı olmadıysa null döndürür.

getContentType(): ?string

Yüklenen dosyanın MIME içerik türünü imzasına göre saptar. Yükleme başarılı olmadıysa ya da saptama başarısız olduysa null döndürür.

fileinfo PHP eklentisini gerektirir.

getUntrustedName(): string

Tarayıcının gönderdiği özgün dosya adını döndürür.

Bu metodun döndürdüğü değere güvenmeyin. Bir istemci, uygulamanızı bozma ya da ele geçirme niyetiyle kötü niyetli bir dosya adı gönderebilir.

getSanitizedName(): string

Temizlenmiş dosya adını döndürür. Yalnızca ASCII karakterleri [a-zA-Z0-9.-] içerir. Ad böyle karakterler içermiyorsa 'unknown' döndürür. Dosya JPEG, PNG, GIF, WebP ya da AVIF görseliyse doğru dosya uzantısını da döndürür.

fileinfo PHP eklentisini gerektirir.

getSuggestedExtension(): ?string

Saptanan MIME türüne karşılık gelen uygun dosya uzantısını (nokta olmadan) döndürür.

fileinfo PHP eklentisini gerektirir.

getUntrustedFullPath(): string

Dizin yüklemesi sırasında tarayıcının gönderdiği özgün dosya yolunu döndürür. Tam yol yalnızca PHP 8.1 ve sonrasında kullanılabilir. Önceki sürümlerde bu metot özgün dosya adını döndürür.

Bu metodun döndürdüğü değere güvenmeyin. Bir istemci, uygulamanızı bozma ya da ele geçirme niyetiyle kötü niyetli bir dosya adı gönderebilir.

getSize(): int

Yüklenen dosyanın boyutunu döndürür. Yükleme başarılı olmadıysa 0 döndürür.

getTemporaryFile(): string

Yüklenen dosyanın geçici konumunun yolunu döndürür. Yükleme başarılı olmadıysa '' döndürür.

__toString(): string

Yüklenen dosyanın geçici konumunun yolunu döndürür. Bu, FileUpload nesnesinin doğrudan dize olarak kullanılmasını sağlar.

isImage(): bool

Yüklenen dosya JPEG, PNG, GIF, WebP ya da AVIF görseliyse true döndürür. Saptama imzasına dayanır ve dosyanın tamamının bütünlüğünü doğrulamaz. Bir görselin bozuk olup olmadığı, örneğin onu yüklemeyi deneyerek belirlenebilir.

fileinfo PHP eklentisini gerektirir.

getImageSize(): ?array

Yüklenen görselin boyutlarını içeren [genişlik, yükseklik] çiftini döndürür. Yükleme başarılı olmadıysa ya da geçerli bir görsel değilse null döndürür.

toImage(): Nette\Utils\Image

Görseli bir Image nesnesi olarak yükler. Yükleme başarılı olmadıysa ya da geçerli bir görsel değilse Nette\Utils\ImageException fırlatır.

versiyon: 4.x