---
title: 'Form İşleme'
source: 'https://academia.sh/tr/kurslar/php-temelleri/form-isleme'
course: 'PHP Temelleri'
language: tr
updated: '2026-10-21T05:03:34+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Geçersiz bir form değerinin hangi kanaldan duyulduğunu ölçerek gösterir'
    - 'Bir POST formunu yerleşik sunucuya göndererek doğrulama ve çıktıda kaçırma sonucunu gözlemler'
    - 'Geçerli 0 değerini başarısızlıktan katı karşılaştırmayla ayırır'
---

# Form İşleme

Formdan gelen dizgilerin filter_var ile doğrulanması: başarısızlığın dönüş değeriyle duyulması, null'a çevrilmesi ve geçerli 0 değerinin başarısızlıkla karışması.

Süper Küresel Değişkenler dersinde istek verisi her zaman dizgi olarak geldi ve eksik anahtar uyarı kanalından duyuldu. Bu derste anahtar var, ama içeriği beklenen biçimde değil: sayı beklenen alana `12a` gelmiş. PHP bu değerle karşılaşınca bir şey söyler mi, söylerse hangi kanaldan?

Formun HTML yapısını ve alanların nasıl kurulduğunu M14 anlattı; burada yalnız gönderilen verinin sunucu tarafında nasıl süzüldüğü ölçülüyor. Doğrulama işi için PHP'nin `filter_var` fonksiyonu kullanılır: bir değeri ve bir süzgeç sabitini alır, süzgeç değeri kabul ederse değeri uygun tipte döndürür, kabul etmezse `false` döndürür. Çıktıda kaçırma (escaping) için `htmlspecialchars` kullanılır; kaçırmanın neden gerektiği ve ona karşı alınacak önlemlerin sınıflandırması M25'in konusudur.

## Geçersiz Değer Dönüşle Duyulur

İlk ölçüm komut satırında yapılır ve süzgeci elle verilen dizgilerle sınar.

```php
<?php
// suzgec.php — filter_var'in gecerli ve gecersiz girdideki donusleri
function yaz(mixed $deger): string
{
    return match (true) {
        $deger === null => 'null',
        is_bool($deger) => $deger ? 'true' : 'false',
        default => get_debug_type($deger) . ' ' . $deger,
    };
}

$olcumler = [
    'gecerli sayi'          => filter_var('12', FILTER_VALIDATE_INT),
    'gecersiz form sayisi'  => filter_var('12a', FILTER_VALIDATE_INT),
    'null_on_failure'       => filter_var('12a', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE),
];

foreach ($olcumler as $ad => $sonuc) {
    printf("%-24s%s\n", $ad, yaz($sonuc));
}
```

```
gecerli sayi            int 12
gecersiz form sayisi    false
null_on_failure         null
```

`12` için fonksiyon `int 12` döndürür: dizgi tam sayıya çevrilmiştir. `12a` için `false` döndürür. Fonksiyon bir uyarı bildirmedi, bir istisna fırlatmadı ve yürütme sürdü; sorun yalnız dönüş değerine bakan kod için duyuluyor. Bu kursun **dönüş** sınıfıdır: sinyal kendiliğinden gelmez, çağıranın değeri sorgulaması gerekir. **IY8.** Bu ölçümde fonksiyonların hiçbiri `E_WARNING` üretmiyor; bu bir ayar değil, `filter_var`'ın tanımlı davranışıdır, bu yüzden ölçümde bir hata işleyicisi kurulmadı.

Üçüncü satır, `FILTER_NULL_ON_FAILURE` bayrağının başarısızlığı `false` yerine `null`'a çevirdiğini gösterir. Kanal değişmez, hâlâ dönüş değeridir; yalnız değerin kendisi farklıdır. Bayrağın anlamı sonraki bölümde netleşir: `false`, mantıksal süzgeç için geçerli bir sonuçtur ve bu bayrak onu başarısızlıktan ayırmak için vardır.

## Formu Sunucuya Göndermek

Gerçek bir form gönderimini yerleşik sunucuyla ölçeriz. Betik iki alan okur: `yas` bir tam sayı olmalı, `ad` kullanıcı metnidir ve çıktıya kaçırılarak yazılır.

```php
<?php
// form.php — POST ile gelen yasi dogrular, adi kacirarak yazar
$yas = filter_var($_POST['yas'] ?? '', FILTER_VALIDATE_INT);
$ad = $_POST['ad'] ?? '';

if ($yas === false) {
    echo "gecersiz yas\n";
} else {
    echo 'yas=', $yas, "\n";
}
echo 'ad=', htmlspecialchars($ad), "\n";
```

```bash
# sunucu.sh — formu yerlesik sunucuya gonderir
php -S 127.0.0.1:8082 -d display_errors=0 >/dev/null 2>&1 &
pid=$!
for i in $(seq 1 50); do curl -s -o /dev/null http://127.0.0.1:8082/form.php && break; sleep 0.1; done
echo '--- gecerli'
curl -s -d 'yas=30' --data-urlencode 'ad=Ayse' -w 'durum=%{http_code}\n' http://127.0.0.1:8082/form.php
echo '--- gecersiz yas'
curl -s -d 'yas=12a' --data-urlencode 'ad=Ayse' -w 'durum=%{http_code}\n' http://127.0.0.1:8082/form.php
echo '--- etiketli ad'
curl -s -d 'yas=30' --data-urlencode 'ad=<b>Ayse</b>' -w 'durum=%{http_code}\n' http://127.0.0.1:8082/form.php
kill $pid
```

```
--- gecerli
yas=30
ad=Ayse
durum=200
--- gecersiz yas
gecersiz yas
ad=Ayse
durum=200
--- etiketli ad
yas=30
ad=&lt;b&gt;Ayse&lt;/b&gt;
durum=200
```

Geçerli gönderimde `yas=30` yazıldı. Geçersiz gönderimde betik `gecersiz yas` yazdı, ama durum kodu yine **200**: sunucu açısından istek başarıyla işlendi, çünkü doğrulama sonucu PHP için bir hata değil, kodun kendi verdiği bir karardır. Doğrulamanın başarısızlığını istemciye bildirmek, kodun bir durum kodu ya da ileti seçmesine bağlıdır; PHP bunu kendiliğinden yapmaz. **IY9.** Durum kodu `false` dönüşünün yaşandığını söylemez; 200 görmek doğrulamanın geçtiği anlamına gelmez.

Üçüncü gönderimde `ad` alanındaki etiket, `htmlspecialchars` sayesinde `&lt;b&gt;Ayse&lt;/b&gt;` olarak yazıldı. Kaçırma olmasaydı tarayıcı bu metni biçimlendirme olarak yorumlardı. Bu fonksiyon dönüş değeriyle de sessizdir: hiçbir kanal, değerin etiket içerdiğini bildirmez.

## Süzgeç Seçenekleri Aralığı Daraltır

Tip kontrolü çoğu zaman yetmez: yaş alanına `150` ya da `-5` yazan biri geçerli bir tam sayı göndermiştir ama geçerli bir yaş göndermemiştir. `filter_var` bunu üçüncü argümandaki `options` dizisiyle çözer; `min_range` ve `max_range` anahtarları kabul edilen aralığı belirler. Ayrıca süzgeç, değerin başındaki ve sonundaki boşlukları kırpar; bu yüzden formdan gelen `' 30 '` gibi bir değer geçerli sayılır.

```php
<?php
// aralik.php — tamsayi suzgecinde aralik ve bosluk davranisi
$secenekler = ['options' => ['min_range' => 0, 'max_range' => 120]];

$girdiler = ['30', ' 30 ', '150', '-5', '3.0'];
foreach ($girdiler as $girdi) {
    $sonuc = filter_var($girdi, FILTER_VALIDATE_INT, $secenekler);
    printf("%-8s%s\n", '[' . $girdi . ']', $sonuc === false ? 'false' : 'int ' . $sonuc);
}
```

```
[30]    int 30
[ 30 ]  int 30
[150]   false
[-5]    false
[3.0]   false
```

Aralığın dışında kalan `150` ve `-5` değerleri `12a` ile aynı yolu izler: ikisi de `false` döndürür. Çağıran bakımından üç farklı sorun, yani biçim hatası, üst sınırın aşılması ve alt sınırın aşılması, tek bir değere indirgenir. Hangisinin olduğunu öğrenmek için kodun girdiyi yeniden incelemesi gerekir; dönüş kanalı yalnız başarısızlığın olduğunu söyler, nedenini taşımaz. `3.0` da reddedilir, çünkü süzgeç ondalık gösterimi tam sayı kabul etmez. **IY10.** Burada gösterilen kırpma ve ondalık davranışı ölçümün çalıştığı PHP 8 ailesine aittir; ders sınır değerlere güvenmez, aralığı her çağrıda kendisi verir.

## Mantıksal Süzgeç `false`'u Başarısızlıktan Ayırır

`FILTER_NULL_ON_FAILURE` bayrağının asıl işi mantıksal süzgeçte görünür. `FILTER_VALIDATE_BOOLEAN` için `false` geçerli bir sonuçtur: `"false"`, `"0"` ve boş dizgi onun kabul edilen yazılışlarıdır. Bayrak olmadan, hem geçerli `false` hem tanınmayan bir metin `false` döndürür ve çağıran ikisini ayıramaz. Bayrakla tanınmayan metin `null` olur ve ayrım değerin kendisinde kalır.

```php
<?php
// mantiksal.php — mantiksal suzgecte gecerli false ile basarisizligin ayrimi
function yaz(mixed $deger): string
{
    return $deger === null ? 'null' : ($deger ? 'true' : 'false');
}

foreach (['true', 'on', 'false', '0', '', 'abc'] as $girdi) {
    $bayraksiz = filter_var($girdi, FILTER_VALIDATE_BOOLEAN);
    $bayrakli = filter_var($girdi, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
    printf("%-8s bayraksiz=%-6s bayrakli=%s\n", '[' . $girdi . ']', yaz($bayraksiz), yaz($bayrakli));
}
```

```
[true]   bayraksiz=true   bayrakli=true
[on]     bayraksiz=true   bayrakli=true
[false]  bayraksiz=false  bayrakli=false
[0]      bayraksiz=false  bayrakli=false
[]       bayraksiz=false  bayrakli=false
[abc]    bayraksiz=false  bayrakli=null
```

Bayraksız sütunda `false`, `0`, boş dizgi ve `abc` aynı görünür; yalnız `abc` gerçekten geçersizdir. Bayrak `abc` için `null` döndürür, diğerleri geçerli `false` kalır. Bu, önceki bölümlerde sözü edilip ölçülmemiş iddiadır: bayrak başarısızlığı yeni bir kanala taşımaz, mevcut dönüş kanalında `false` ile `null` arasında bir ayrım açar. **IY11.** Bu ayrımdan yararlanmak için çağıranın `=== null` sınaması yapması gerekir; değilleme işleci `null` ile `false`'u yine aynı sayar.

## Eksik Alan Geçersiz Değerle Aynı Görünür

Doğrulamanın bir tuzağı, alanın hiç gönderilmemesidir. Önceki `form.php` eksik alanı `?? ''` ile boş dizgiye çevirir ve süzgeç boş dizgiyi reddeder; sonuç, `12a` gönderilmiş gibi `false` olur. Ayrım için anahtarın varlığı ayrıca sınanır.

```php
<?php
// eksik_alan.php — eksik alan ile gecersiz alanin ayni false'a inmesi
$yas = filter_var($_POST['yas'] ?? '', FILTER_VALIDATE_INT);
$var = array_key_exists('yas', $_POST) ? 'evet' : 'hayir';
echo 'suzgec=', $yas === false ? 'false' : $yas, ' alan_var=', $var, "\n";
```

```bash
# eksik_alan.sh — alanli ve alansiz iki POST gonderir
php -S 127.0.0.1:8082 -d display_errors=0 >/dev/null 2>&1 &
pid=$!
for i in $(seq 1 50); do curl -s -o /dev/null http://127.0.0.1:8082/eksik_alan.php && break; sleep 0.1; done
echo '--- yas=12a'
curl -s -d 'yas=12a' -w 'durum=%{http_code}\n' http://127.0.0.1:8082/eksik_alan.php
echo '--- alan yok'
curl -s -d 'ad=Ayse' -w 'durum=%{http_code}\n' http://127.0.0.1:8082/eksik_alan.php
kill $pid
```

```
--- yas=12a
suzgec=false alan_var=evet
durum=200
--- alan yok
suzgec=false alan_var=hayir
durum=200
```

İki istekte süzgeç sonucu aynıdır: `false`. Yalnız `array_key_exists` farkı gösterir. Eksik alan Süper Küresel Değişkenler dersinde uyarı kanalındaydı; `?? ''` onu sessiz kanala çekti ve doğrulama sonunda dönüş kanalına indirdi. Üç kanal, tek bir satırda zincirlenmiştir ve sonuç hiçbir noktada hangisinin devrede olduğunu söylemez. **IY12.** Hangi kanalın seçildiğini bilmeyen kod, "alan yok" ile "alan bozuk" durumlarını aynı hata iletisiyle karşılar.

## Diğer Süzgeçler Aynı Dönüş Yolunu Kullanır

Tam sayı ve mantıksal süzgeçler tek örnek değildir. E-posta ve ondalık sayı süzgeçleri de aynı biçimde çalışır: geçerli girdide değeri, geçersiz girdide `false` döndürür. Ondalık sayıda ayırıcı nokta olarak kabul edilir; virgül kullanan bir kullanıcının girdisi reddedilir.

```php
<?php
// digerleri.php — e-posta ve ondalik sayi suzgeclerinin donusleri
$olcumler = [
    'eposta gecerli'    => filter_var('ad@ornek.test', FILTER_VALIDATE_EMAIL),
    'eposta gecersiz'   => filter_var('ad@', FILTER_VALIDATE_EMAIL),
    'ondalik nokta'     => filter_var('1.5', FILTER_VALIDATE_FLOAT),
    'ondalik virgul'    => filter_var('1,5', FILTER_VALIDATE_FLOAT),
];

foreach ($olcumler as $ad => $sonuc) {
    printf("%-18s%s\n", $ad, $sonuc === false ? 'false' : get_debug_type($sonuc) . ' ' . $sonuc);
}
```

```
eposta gecerli    string ad@ornek.test
eposta gecersiz   false
ondalik nokta     float 1.5
ondalik virgul    false
```

Dört süzgeç de aynı yoldan konuşur: sinyal dönüş değerindedir ve ayrıntı yoktur. `1,5` reddi, süzgecin yerel ayara bakmadığını gösterir; ayırıcıyı değiştirmek çağıranın görevidir. **IY13.** Bu dersin bütün ölçümleri tek bir sonuca varır: PHP girdinin geçersizliğini istemciye bildirmez, çağırana yalnız bir değer verir ve sonrası kodun kararıdır.

## Sınırlayıcı Ölçüm

Dönüş kanalının zayıf noktası, başarısızlığı sınamanın yoludur. Başarısızlığı `false`'tan ayırmanın en kısa yolu değeri değilleme işleciyle sınamaktır, ama `0` geçerli bir tam sayıdır.

```php
<?php
// sifir.php — gecerli 0 ile basarisizligin ayni sinanmasi
$olcumler = [
    'sifir'   => filter_var('0', FILTER_VALIDATE_INT),
    'gecersiz' => filter_var('0a', FILTER_VALIDATE_INT),
];

foreach ($olcumler as $ad => $sonuc) {
    $kisa = !$sonuc ? 'basarisiz sanildi' : 'gecerli';
    $kati = $sonuc === false ? 'basarisiz' : 'gecerli';
    printf("%-10s%s: %-18s%s: %s\n", $ad, 'degilleme', $kisa, 'kati', $kati);
}
```

```
sifir     degilleme: basarisiz sanildi kati: gecerli
gecersiz  degilleme: basarisiz sanildi kati: basarisiz
```

`0` için `filter_var` geçerli bir `int 0` döndürür. Değilleme işleciyle sınanınca bu değer, `false` ile aynı görünür ve geçerli girdi başarısız sayılır. Katı karşılaştırma (`=== false`) ikisini ayırır. **IY14.** Bu bir PHP tuhaflığı değil, dönüş kanalının doğal sınırıdır: kanal tek bir değerin içine hem sonucu hem başarısızlığı sığdırır ve ayrımı çağıran yapar. Bayrak `FILTER_NULL_ON_FAILURE` ayrımı değerin kendisine taşır, ama o zaman mantıksal süzgeçte geçerli `false` ile `null` ayrışır; her durumda sinyali okuyan kodun hangi değerin hangi anlama geldiğini bilmesi gerekir.

## Özet

- Form verisi `string` gelir ve `filter_var` onu süzgeçle sınar: geçerliyse uygun tipte değer, geçersizse `false` döner.
- Bu dersin ölçü sınıfı **dönüş**tür: geçersiz `12a` için uyarı da istisna da yoktur; sorun yalnız dönüş değerine bakan kod için duyulur.
- Doğrulama başarısızlığı durum kodunu değiştirmez: betik kendi kararıyla `gecersiz yas` yazsa da yanıt 200 kalır.
- `htmlspecialchars` etiketleri `&lt;` ve `&gt;` biçimine çevirir; kaçırmanın sınıflandırması M25'indir.
- Geçerli `0`, değilleme işlecinde başarısızlıkla aynı görünür; katı karşılaştırma (`=== false`) ikisini ayırır.

## Sonraki Adım

Bu derste istek tek bir değer taşıyordu ve eksik ya da bozuk alan bir kontrolle yakalandı. Dosya yüklemede ise istek, dosyanın kendisi ve ona eşlik eden bir durum kodu taşır. Dosya Yükleme dersi, yüklenmemiş bir dosyanın `move_uploaded_file` ile taşınmaya çalışılınca ne döndürdüğünü ve sunucu sınırı aşıldığında `$_FILES` ile `$_POST` içinde neyin kaldığını ölçüyor.
