İçeriğe geç
Muhammet Şafak
Diller 3 dk okuma

PHP 8.2 yolda: readonly sınıflar ve yeni tipler

PHP 8.2 ile gelen readonly sınıflar, DNF tipler ve tek başına tip bildirimleri; bu eklemelerin domain modellemesine etkisi.


PHP 8.2’nin yıl sonunda yayımlanmasını bekliyorum. Bu yazıyı sürüm henüz çıkmadan, RFC’leri ve beta paketini inceleyerek yazıyorum — çünkü 8.2, mütevazı başlıklarına rağmen benim için anlamlı bir şeyi kolaylaştırıyor: immutability’yi sınıf düzeyinde ifade etmeyi.

readonly sınıflar

PHP 8.1 ile readonly property gelmişti: bir özelliği yalnızca bir kez, kurucu metot içinde atayabiliyordunuz. İşe yarıyordu ama on alanlı bir value object’te her alanın başına readonly yazmak gürültü yaratıyordu.

8.2 ile sınıfın tamamını readonly ilan edebiliyorsunuz:

readonly class Para
{
    public function __construct(
        public int $kurus,
        public string $birim = 'TRY',
    ) {}
}

Bu sınıfın bütün özellikleri otomatik olarak readonly olur. Bir Para nesnesi kurulduktan sonra değiştirilemez; değiştirmek isteyen yeni bir nesne üretir. Yıllardır value object’leri elle “değiştirilemez” tutmaya çalışıyordum; artık bu garantiyi dil veriyor.

readonly sınıfta bir kısıtlama

Readonly sınıfların bir sınırı var: bağımsız tipler dahil, tüm özellikler bir tipe sahip olmak zorunda. Tipsiz bir özelliğe readonly uygulanamıyor; readonly sınıfta da aynı kural geçerli. Dolayısıyla public $alan yazmak derleme hatası verecek; public mixed $alan yazmak gerekiyor.

Bu küçük bir kısıtlama gibi görünse de, yıllar önce tipsiz özelliklerle yazılmış value object’leri readonly sınıfa geçirirken gündeme gelebilir. Geçiş planlarken her özelliğin tipini kontrol etmek gerekiyor.

DNF tipler

İkinci ekleme ayrık normal form (Disjunctive Normal Form) tipleri. Bugüne kadar A&B (kesişim) ve A|B (birleşim) tiplerini ayrı ayrı kullanabiliyorduk ama bir arada değil. 8.2 ile ikisini birleştirebiliyorsunuz:

function kaydet((Countable&Iterator)|null $veri): void

Burada parametre ya Countable ve Iterator interface’lerinin ikisini birden karşılayan bir nesne ya da null olabilir. Günlük kodda sık gerekmez; ama kütüphane sınırlarında tip imzasını dürüst tutmayı sağlıyor.

Bunu en çok, nesne koleksiyonlarını işleyen yardımcı fonksiyonlarda kullanmak istediğimde karşıma çıkıyordu. “Hem gez hem say” diyebileceğim bir tip tanımlamak için Traversable&Countable yazmak istiyordum; 8.2 öncesinde bunu tip imzasına yazmanın temiz yolu yoktu.

Tek başına null, true, false

Önceden null tek başına bir dönüş tipi olarak yazılamıyordu; bir ?something içine gömmek gerekiyordu. 8.2 ile null, true ve false bağımsız tipler haline geliyor:

function bul(int $id): User|null { /* ... */ }
function aktifMi(): true { /* ... */ }

Küçük bir düzeltme ama tip imzasının niyeti birebir anlatmasını sağlıyor.

Dinamik özelliklerin kullanımdan kalkması

8.2 ayrıca tanımlanmamış bir özelliğe değer atamayı — yani dinamik özelliği — artık uyarıyla işaretliyor. Yıllar içinde $nesne->yanlisYazilmisAlan = 1 satırı yüzünden saatlerce hata aradığım oldu. Bu davranışın kapanması, sınıfların ne tuttuğunu açıkça bildirmeye zorluyor; bu da iyi bir baskı.

Eski projelerde bu uyarılarla karşılaşmak kaçınılmaz olacak; bazı kod tabanlarında dinamik özellik atama kasıtlı kullanılmış olabilir. Bu geçiş için #[AllowDynamicProperties] özniteliği (attribute) geçici bir kaçış kapısı sunuyor. Ama kalıcı çözüm, özellikleri açıkça bildirmek.

Neye yarıyor

Bu eklemelerin ortak teması şu: dil, niyeti ifade etmek için daha fazla yer açıyor. Readonly sınıf “bu nesne kurulduktan sonra sabittir” der; DNF tipler “bu parametre tam olarak şudur” der; dinamik özelliğin kapanması “bu sınıf yalnızca bunları tutar” der.

Bu tür eklemeler beni PHP’de yapı inşa etme biçimimi değiştiriyor. 8.1’deki enum ve readonly property’lerden sonra 8.2’deki readonly sınıf, dil ile niyet arasındaki boşluğu bir adım daha kapıyor. Sürüm çıkar çıkmaz value object’lerimi readonly sınıfa taşımayı planlıyorum. Büyük bir göç değil; ama kodun, daha önce yorum satırıyla ya da ekip disipliniyle koruduğum kuralları artık dilin kendisiyle anlatması hoşuma gidiyor. İyi bir sürüm, az kod yazdırarak çok şey garanti edendir.

Etiketler: #PHP
Paylaş:

İlgili Yazılar

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi