# Kullanıcı Girdisini Filtreleme

https://dev.wisecp.com/tr/kullanici-girdisini-filtreleme

Tarayıcıdan gelen her değer `Filter` üzerinden okunur; sınıf değeri, başka hiçbir yere ulaşmadan önce onu alacak kodun beklediği karakterlere indirger.

## Genel Bakış

WISECP `$_POST`, `$_GET` ya da `$_REQUEST` değerlerini doğrudan okumaz. Tek bir sınıf, superglobal içindeki yolu ve bir filtre adını alır; değeri o filtrenin izin verdiği karaktere indirgenmiş hâlde yanıtlar.

Filtreleme, girdi güvenliğinin yarısıdır. Diğer yarısı doğrulamadır: filtreleme karakter siler, doğrulama geriye kalanın kullanılabilir olup olmadığına karar verir. Filtreden geçmiş ama anlamsız bir değeri yine sizin kontrolünüz reddetmelidir.

## Referans

### İmzalar

```php
public static function init($arg = null, $mod = false, $special = false);

public static function GET($arg = '');
public static function POST($arg = '');
public static function REQUEST($arg = '');
public static function FILES($arg = '');
public static function SERVER($arg = '');

public static function html_clear($arg = null, $allow = '');
public static function phone($arg = '');
public static function route($arg = '', $special = '');
public static function permalink($str, $options = []);
```

Buradaki her şey statiktir. Aşağıdaki tablodaki adların çoğu aynı iki argümanı alan bağımsız birer metottur. `Filter::rnumbers($value)`, `init`'in yolu çözdükten sonra yaptığı işi yapar. Üçü bu kuralın dışında kalır. `hclear` adında bir metot yoktur, o ad `html_clear`'ı çağırır. `false` filtrelerden biri değil, filtrenin yokluğudur. `domain` ise yalnız değeri alan bir metottur.

### init'in Üç Argümanı

- **$arg**: `POST/user/name` gibi bir kaynak yolu ya da düz bir değer. Beş kaynak adından biriyle başlamayan bir dize olduğu gibi filtrelenir, yani `Filter::init($text, "hclear")` geçerlidir. İlk argüman boşsa çağrı `false` yanıtlar.
- **$mod**: Filtre adı; tablodaki on dokuz değerden biri. Varsayılan `false` değeri dokunmadan döndürür; tanınmayan bir ad da öyle.
- **$special**: Filtrenin izin listesine katılan ek karakterler, düzenli ifade söz dizimiyle. `a-z` bir aralıktır; düz bir tire ya da eğik çizgi kaçış ister. `$mod` `false` bırakılırsa bu argüman, işaretleme temizlendikten sonra uygulanan izin listesinin tamamı olur.

### Kaynak Yolları

İlk yol parçası superglobal'i adlandırır, gerisi içine yürür: `POST/user/name`, istek gövdesindeki `user` dizisinin `name` anahtarını okur. Aynı beş erişimci herkese açıktır ve ham değeri filtresiz döndürür. Argümansız çağrıldıklarında superglobal'in tamamını verirler; olmayan bir anahtarda `false` verirler, hiçbir zaman `null` değil.

- **Filter::GET($arg)**: Sorgu dizesi. Yol öneki `GET/`.
- **Filter::POST($arg)**: İstek gövdesi. Yol öneki `POST/`.
- **Filter::REQUEST($arg)**: İki kaynak birden. Yol öneki `REQUEST/`; operation adı böyle okunur.
- **Filter::FILES($arg)**: Bir alan adına ait yükleme kaydı, PHP'nin kurduğu hâliyle. Yol öneki `FILES/`.
- **Filter::SERVER($arg)**: Sunucu değişkeni, örneğin `REMOTE_ADDR`. Yol öneki `SERVER/`.

### Filtre Tipleri

Son sütun, anahtar istekte yokken elinize geçen değerdir. Yanıt filtreden filtreye değişir.

| Filtre | Neyi tutar | Dönüş | Anahtar yoksa |
| --- | --- | --- | --- |
| `false` | Değeri, işaretleme dahil, dokunmadan | mixed | `false` |
| `hclear` | Varlıklar çözüldükten sonra etiketleri temizlenmiş metin | string | boş dize |
| `text` | Aynısı, ardından iki tırnak karakteri sayısal varlığa çevrilir | string | boş dize |
| `dtext` | `hclear` ile aynı, tırnaklara dokunulmaz | string | boş dize |
| `letters_numbers` | Latin harfleri ve rakamlar | string | `false` |
| `letters` | Latin harfleri ve seçili dilin kendi harfleri | string | boş dize |
| `numbers` | Rakam ve tire | string | `false` |
| `rnumbers` | Rakam ve tire, sonra tam sayıya çevrilir | int | `0` |
| `amount` | Rakam, tire, nokta, virgül; ayraçlar yazıldığı gibi kalır | string | boş dize |
| `rate` | Aynısı; virgül ondalık ayracı sayılır, binlik noktaları düşer | float | `0.0` |
| `ip` | Harf, rakam, tire, nokta, iki nokta; v6 böylece korunur | string | `false` |
| `domain` | Harf, rakam, nokta, tire; ardından küçük harfe iner | string | boş dize |
| `email` | Harf, rakam ve `@ . + _` karakterleri | string | boş dize |
| `route` | Harf, rakam, tire, alt çizgi, nokta; önce `../` silinir | string | boş dize |
| `folder` | Harf, rakam, eğik çizgi, tire, alt çizgi, nokta | string | boş dize |
| `file` | Harf, dil harfleri, rakam, tire, alt çizgi, nokta | string | boş dize |
| `noun` | Harf, rakam, virgül, nokta, boşluk | string | boş dize |
| `identity` | Rakam ve tire; `numbers` ile aynı kural | string | `false` |
| `password` | Her şeyi, değiştirmeden | mixed | `false` |

`password` bilerek geçirgendir: güçlü bir parola tam olarak diğer filtrelerin kaldırdığı karakterlerden kuruludur ve onları sessizce silmek ziyaretçinin yazdığını değiştirir. `hclear`, `text`, `dtext`, `email`, `domain`, `identity` ve `password` üçüncü argümanı yok sayar.

### Doğrudan Çağrılan Yardımcılar

- **html_clear($arg, $allow)**: Varlıkları çözer, sonra etiketleri temizler. İkinci argüman, PHP'nin beklediği biçimde izin listesidir; örneğin `'<b><i>'`. Etiket korumanın tek yolu budur; `hclear` hiçbir zaman izin listesi geçirmez.
- **phone($arg)**: Yalnız rakam; ülke öneki, boşluk ve parantez kaybolur. Tek argüman, izin listesi yok.
- **route($arg, $special)**: `../` dizisini siler, ardından harf, rakam, tire, alt çizgi ve noktayı tutar. Bir rota parçası eğik çizgi taşıyorsa kaçışlanmış hâlini ikinci argümanla ekleyin.
- **permalink($str, $options)**: Slug üreticisi. Seçenekler ve varsayılanları: `delimiter` (tire), `limit` (yok), `lowercase` (true), `replacements` (önce uygulanan desenler, boş) ve `transliterate` (true).

## Örnek

Alan adları iki taraf arasındaki sözleşmedir. Formun gönderdiği ad, yolun harf harf yazdığı addır.

```html
<input type="hidden" name="operation" value="update_client">
<input type="hidden" name="id" value="42">
<input type="text"     name="user[name]">
<input type="email"    name="email">
<input type="password" name="password">
<input type="text"     name="slug">
```

```php
public function update_client(Operation $operation): bool
{
    $operation->demo();

    $id    = (int) Filter::init("POST/id", "rnumbers");
    $name  = Filter::init("POST/user/name", "hclear");
    $email = Filter::init("POST/email", "email");
    $pass  = Filter::init("POST/password", "password");
    $slug  = Filter::init("POST/slug", "route", "\/");

    // Filtreleme doğrulama değildir: bunlar temiz, ama kullanılabilir olmak zorunda değil.
    if (!$id)                                          throw new Exception(Language::gc("error/id-required"));
    if ($name === '')                                  throw new Exception(Language::gc("error/name-required"));
    if (!filter_var($email, FILTER_VALIDATE_EMAIL))    throw new Exception(Language::gc("error/email-invalid"));

    $bio = Filter::html_clear(Filter::POST("bio"), '<b><i><a>');

    return $operation->output(['status' => "successful"]);
}
```

## Tuzaklar

> **Yanlış yazılmış filtre adı ham değeri döndürür**
> 
> Ad bir listeyle karşılaştırılır ve eşleşmeyen her şey, işaretlemesiyle birlikte dokunulmamış değere düşer. `Filter::init("POST/v", "number")` sayısal bir okuma değildir, hiç okuma değildir. İzin listesini ikinci sıraya yazmak da aynı sonucu verir: `Filter::init("POST/v", "a-z")` hiçbir şeyi filtrelemez.

> **Olmayan anahtar iki kez aynı yanıtı vermez**
> 
> Beş erişimci her zaman `false` yanıtlar, yani varlık kontrolü `!== false` ile yazılır. `init` üzerinden yanıt filtreye aittir; tablonun son sütunu bunu gösterir. `!== ''` ya da `!== null` biçiminde yazılan bir kontrol bazılarında her istekte doğrudur.

> **Üçüncü argüman düzenli ifade söz dizimidir**
> 
> Yazıldığı gibi bir karakter sınıfına yapıştırılır. Filtreyi kastettiğinizden çok daha fazla genişletebilir, kaçak bir köşeli parantez de deseni bozar. Düz olması gerekeni kaçışlayın ve bu argümanı asla kullanıcı girdisinden kurmayın.

> **Dizi değerler skaler filtreden geçmez**
> 
> Diziyi yalnız `password` ve filtresiz okuma geçirir. Kalanı filtresine göre `false`, boş dize ya da sıfır yanıtlar. Gruplanmış alan tek değer gibi değil, anahtar anahtar okunur.

## İlgili Makaleler

- [Operation'lar](https://dev.wisecp.com/tr/operationlar)
- [Hata Yönetimi](https://dev.wisecp.com/tr/hata-yonetimi)
- [Kod Konvansiyonları](https://dev.wisecp.com/tr/kod-konvansiyonlari)
