Ders 08 / 21
Form ve Doğrulama
Kural dizgeleriyle çalışan bir doğrulayıcı kurulur; geçersiz girdide kayıt adımının atlandığı, geçerli girdide koştuğu ve ilk hatada durmanın sonraki kuralı atladığı ölçülür.
Yayın Güncelleme
Bu derste
- Kural dizgelerini çözen bir doğrulayıcı ve hata iletisi üreten bir form eylemi kurmak
- Geçersiz girdide kayıt adımının atlandığını, 422 durumuyla birlikte ölçmek
- Geçerli girdide kayıt adımının koştuğunu karşıt ölçüm olarak göstermek
- İlk hatada durmanın sonraki kuralı atlamasını ve kullanıcıya giden ileti sayısına etkisini okumak
İçindekiler
Şablon önüne konan her değeri basar; değerin yazılması gereken biçimde olup olmadığına bakmaz. O kontrol formun eyleminde yapılır: kullanıcıdan gelen girdi kurala uymazsa kayıt adımına ulaşmamalıdır. Peki ulaşmadığını nereden bilirsiniz? Bu derste soru, kuralın tutmadığı istekte kayıt adımının ne olduğudur.
Ölçü ekseni önceki dersteki gibi, beklenen parça bu istekte koştu mu sorusudur. Karar sırası sinifla() fonksiyonunun kendisidir: koştu, ertelendi, atlandı, bağlanmadı. Bu dersin ağırlıklı sınıfı atlandı‘dır: kayıt adımı eylemin yoluna konmuştur, ama çağrılmaz. Atlanan adım istemciye bir durum koduyla görünür; burada bu kod 422’dir.
GV4. Form girdisi, istek gövdesinden çözülmüş bir dizidir; HTTP katmanı bu derste kurulmaz ve eylem doğrudan bir dizi alır. GV5. Kural dizgesi | ile ayrılmış kurallardan oluşur ve bir kuralın argümanı : ile verilir (en_az:3). GV6. Geçersiz girdi boş ('') ya da kısa ('ab') bir alanla gösterilir; kuralların mantığı özel karakterlerden bağımsızdır. GV7. Hata iletileri ASCII yazılır ki sütun genişliği bozulmasın.
Ölçüm düzeneği değişmeden gelir.
<?php // kostu.php — beklenen bir parça bu istekte koştu mu? declare(strict_types=1); final class Gunluk { public static array $yol = []; // isteğin yoluna konan parçalar public static array $kostu = []; // istek içinde çağrılanlar public static array $ertelenen = []; // isteğin dışına bırakılanlar public static function yeniIstek(): void { self::$yol = self::$kostu = self::$ertelenen = []; } public static function yola(string $parca): void { self::$yol[] = $parca; } public static function kostu(string $parca): void { self::$kostu[] = $parca; } public static function ertele(string $parca): void { self::$ertelenen[] = $parca; } } function sinifla(string $parca): string { return match (true) { in_array($parca, Gunluk::$kostu, true) => 'koştu', in_array($parca, Gunluk::$ertelenen, true) => 'ertelendi', in_array($parca, Gunluk::$yol, true) => 'atlandı', default => 'bağlanmadı', }; }
Doğrulayıcıyı Kurmak
Doğrulayıcı (validation) alan başına kural dizgesini ayrıştırır, her kuralı sırayla çalıştırır ve başarısız olanlar için bir ileti toplar. İki ayrıntı ölçüme bağlıdır. Birincisi, bir alanın bütün kuralları kural çalışmadan önce yola konur; bu yüzden çalışmayan kural atlandı sınıfına düşebilir. İkincisi, kurucudaki seçenek ilk hatada durmayı belirler: durursa aynı alanın sonraki kuralları çağrılmaz.
Form eylemi doğrulayıcıyı çağırır. Girdi geçerli değilse 422 döner, hata iletileri ve eski girdi yanıta konur; eski girdi, formun yeniden gösterilirken alanların boşalmamasını sağlar. Geçerliyse kayıt adımı koşar ve 201 döner. Kayıt adımı eylemin yoluna eylem başlarken konur, çağrısı da yalnızca doğrulama geçtikten sonra yapılır.
<?php // dogrulama.php — kural dizgeleriyle doğrulayıcı ve yazı kaydeden eylem declare(strict_types=1); require_once 'kostu.php'; final class Dogrulayici { public array $hatalar = []; public function __construct(private bool $ilkHatadaDur = true) {} public function dogrula(array $girdi, array $kurallar): bool { $this->hatalar = []; foreach ($kurallar as $alan => $dizge) { $liste = explode('|', $dizge); foreach ($liste as $kural) { Gunluk::yola("kural:$alan:" . explode(':', $kural)[0]); } foreach ($liste as $kural) { if ($this->ilkHatadaDur && isset($this->hatalar[$alan])) break; [$ad, $arguman] = array_pad(explode(':', $kural, 2), 2, null); Gunluk::kostu("kural:$alan:$ad"); $deger = (string) ($girdi[$alan] ?? ''); $gecti = match ($ad) { 'zorunlu' => $deger !== '', 'en_az' => mb_strlen($deger) >= (int) $arguman, }; if (!$gecti) { $this->hatalar[$alan][] = match ($ad) { 'zorunlu' => "$alan zorunludur", 'en_az' => "$alan en az $arguman karakter olmalidir", }; } } } return $this->hatalar === []; } } function yaziKaydet(array $girdi, Dogrulayici $dogrulayici, array $kurallar): array { Gunluk::yola('kayit'); if (!$dogrulayici->dogrula($girdi, $kurallar)) { return [422, ['hatalar' => $dogrulayici->hatalar, 'eski' => $girdi]]; } Gunluk::kostu('kayit'); return [201, ['kaydedilen' => $girdi['baslik']]]; } function yanitYaz(array $yanit): void { [$durum, $govde] = $yanit; echo "durum $durum\n"; foreach ($govde['hatalar'] ?? [] as $alan => $iletiler) { foreach ($iletiler as $ileti) echo " hata $alan: $ileti\n"; } foreach ($govde['eski'] ?? [] as $alan => $deger) echo " eski $alan='$deger'\n"; if (isset($govde['kaydedilen'])) echo " kaydedilen {$govde['kaydedilen']}\n"; }
Geçersiz Girdide Kayıt Adımı
Ölçüm boş bir başlıkla ve iki harfli bir özetle eylemi çağırır. Kurallar: başlık zorunlu, özet en az üç karakter. Beklenen: durum 422, iki hata iletisi, eski girdi yanıtta, kayıt adımı atlandı. Kural parçaları ise ikisi de koştu, çünkü ikisi de çalıştı ve ikisi de tutmadı.
<?php // gecersiz.php — geçersiz girdide kayıt adımı atlanır require_once 'dogrulama.php'; $kurallar = ['baslik' => 'zorunlu', 'ozet' => 'en_az:3']; Gunluk::yeniIstek(); yanitYaz(yaziKaydet(['baslik' => '', 'ozet' => 'ab'], new Dogrulayici(), $kurallar)); foreach (['kural:baslik:zorunlu', 'kural:ozet:en_az', 'kayit'] as $parca) { printf(" %-22s %s\n", $parca, sinifla($parca)); }
durum 422 hata baslik: baslik zorunludur hata ozet: ozet en az 3 karakter olmalidir eski baslik='' eski ozet='ab' kural:baslik:zorunlu koştu kural:ozet:en_az koştu kayit atlandı
İki hata iletisi gittiği hâlde kayıt adımı atlandı: eylemin yoluna konmuştu, çağrılmadı. Bu atlama sessiz değildir; istemci 422 alır ve hangi alanın neden tutmadığını görür. Kural koştu ile tutmadı farklı şeylerdir: ölçü eksenimiz kuralın çalışıp çalışmadığıdır, geçip geçmediği değil. Hata iletisi kuralın çalışmasının sonucudur.
Karşıt Ölçüm: Geçerli Girdi
Aynı eylem geçerli bir girdiyle çağrılır. Beklenen: durum 201, hata yok, kayıt adımı koştu.
<?php // gecerli.php — geçerli girdide kayıt adımı koşar require_once 'dogrulama.php'; $kurallar = ['baslik' => 'zorunlu', 'ozet' => 'en_az:3']; Gunluk::yeniIstek(); yanitYaz(yaziKaydet(['baslik' => 'Ilk yazi', 'ozet' => 'abc'], new Dogrulayici(), $kurallar)); foreach (['kural:baslik:zorunlu', 'kural:ozet:en_az', 'kayit'] as $parca) { printf(" %-22s %s\n", $parca, sinifla($parca)); }
durum 201 kaydedilen Ilk yazi kural:baslik:zorunlu koştu kural:ozet:en_az koştu kayit koştu
Doğrulamanın kendisi iki istekte de aynı biçimde koştu; yalnızca ardındaki adımın kaderi değişti. Kayıt adımı doğrulamadan bağımsız bir kapı değildir, doğrulamanın sonucuna bağlı bir dallanmadır.
Sınırlayıcı Ölçüm
Doğrulayıcı kurucusundaki seçenek, aynı girdide kullanıcıya kaç ileti gideceğini belirler. Özet alanı iki kurala sahip olsun (zorunlu|en_az:3) ve girdi boş olsun. İlk hatada durmayan doğrulayıcıda iki kural da çalışır ve iki ileti toplanır. İlk hatada duran doğrulayıcıda zorunlu tutmaz, en_az çağrılmaz ve tek ileti toplanır.
<?php // durma.php — ilk hatada durmak sonraki kuralı atlatır require_once 'dogrulama.php'; $kurallar = ['baslik' => 'zorunlu', 'ozet' => 'zorunlu|en_az:3']; foreach ([true, false] as $dur) { Gunluk::yeniIstek(); echo $dur ? "ilk hatada durur\n" : "durmaz\n"; yanitYaz(yaziKaydet(['baslik' => 'Ilk yazi', 'ozet' => ''], new Dogrulayici($dur), $kurallar)); foreach (['kural:ozet:zorunlu', 'kural:ozet:en_az', 'kayit'] as $parca) { printf(" %-22s %s\n", $parca, sinifla($parca)); } }
ilk hatada durur durum 422 hata ozet: ozet zorunludur eski baslik='Ilk yazi' eski ozet='' kural:ozet:zorunlu koştu kural:ozet:en_az atlandı kayit atlandı durmaz durum 422 hata ozet: ozet zorunludur hata ozet: ozet en az 3 karakter olmalidir eski baslik='Ilk yazi' eski ozet='' kural:ozet:zorunlu koştu kural:ozet:en_az koştu kayit atlandı
Duran doğrulayıcıda en_az kuralı atlandı, durmayanda koştu; yanıtın durumu iki durumda da 422 ve kayıt iki durumda da atlandı. Kayıt adımının kaderini kuralların tutup tutmaması belirler, ileti sayısını ise duruş seçimi. Boş bir alana ayrıca “en az üç karakter” demek kullanıcıya yeni bilgi vermez; bu yüzden ilk hatada durmak sık seçilir. Ama bir alanın bütün sorunlarını tek turda göstermek isteyen form, ikinci seçeneği kurar. Seçim bir tasarım kararıdır ve yanıtta görünür.
Özet
- Doğrulayıcı kural dizgelerini çözer, hata iletilerini toplar ve eski girdiyi forma geri döndürür.
- Bu dersin ölçü sınıfı
atlandı’dır: geçersiz girdide kayıt adımı eylemin yoluna konmuş olduğu hâlde çağrılmadı; istemci 422 ve iletiler aldı. - Karşıt ölçümde geçerli girdi kayıt adımını
koştusınıfına getirdi ve durum 201 oldu. - Kuralın çalışması (
koştu) kuralın geçmesinden ayrıdır; tutmayan kural da koşmuştur. - İlk hatada durmak aynı alandaki sonraki kuralı
atlandıyapar ve kullanıcıya giden ileti sayısını azaltır; kayıt adımının kaderi değişmez.
Sonraki Adım
Geçerli girdi kayıt adımına ulaştı. Kayıt bir modelin içinden geçtiğinde, kaydedilirken başka neler çalışır? Bir sonraki ders nesne ve tablo bağlamasını ele alır ve model kaydedilirken hangi parçanın koştuğunu ölçer.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.