PHP 8.3: typed class constants ve gelen eklemeler
PHP 8.3 ile gelen tipli sınıf sabitleri, json_validate, #[Override] ve dinamik sabit erişimi; dilin tutarlılık yönündeki adımları.
PHP 8.3 bu ayın sonunda yayımlanacak. Sürüm henüz çıkmadan, beta paketiyle ne getireceğine bakmak istiyorum. 8.3 büyük bir sürüm değil — ama tam da bu yüzden ilgimi çekiyor. Çünkü bu sürümün eklemeleri, dilin daha önce eksik bıraktığı küçük tutarsızlıkları kapatmaya odaklı.
Tipli sınıf sabitleri
Yıllardır sınıf sabitlerine (class constant) tip yazamıyorduk. Bir özelliğe private int $x diyebiliyordunuz ama sabite diyemiyordunuz. 8.3 bunu düzeltiyor:
class HttpDurum
{
public const int BASARILI = 200;
public const string VARSAYILAN_DIL = 'tr';
}
Bu, kozmetik bir ekleme gibi görünür ama bir alt sınıf bir sabiti yeniden tanımladığında tipi koruduğunu garanti eder. Sözleşmenin (contract) bir parçasını daha derleyici düzeyine taşıyor.
Alt sınıflarda gerçek değeri nerede görünüyor?
Kalıtım ile birlikte düşününce tipli sabitler daha anlamlı. Bir interface veya soyut sınıf sabit tanımladığında, alt sınıfın o sabiti doğru tipte tutmasını PHP artık zorunlu kılıyor:
interface Raporlanabilir
{
public const string FORMAT = 'text';
}
class PdfRapor implements Raporlanabilir
{
// Bu geçerli — tip uyuşuyor
public const string FORMAT = 'pdf';
// Bu hata verirdi — int değil string bekleniyor
// public const int FORMAT = 42;
}
Bunu daha önce dokümantasyon yorumuyla ya da @var string gibi PHPDoc işaretleriyle belirtiyorduk; IDE anlıyordu ama runtime anlamıyordu. Artık her ikisi de anlıyor.
#[\Override] özniteliği
İkinci ekleme #[\Override] attribute’u. Bir metodun, üst sınıftaki ya da interface’deki bir metodu gerçekten override ettiğini belirtmenizi sağlar:
class JsonRapor extends Rapor
{
#[\Override]
public function olustur(): string { /* ... */ }
}
Üst sınıftaki metodun adı değişirse ya da silinirse, #[\Override] yazdığınız metot artık hiçbir şeyi ezmediği için PHP hata verir. Daha önce bu tür kopmalar sessizce, çalışma anında ortaya çıkardı. Niyeti yazıya dökmek, onu denetlenebilir kılıyor.
Bu özellik için Java veya Kotlin’e bakan bir göz gerekmiyor; gerçek hayatta defalarca yaşanan bir sorun: bir üst sınıftaki metod adı refactoring sırasında değişiyor, alt sınıfta orijinal adla duran metot artık override değil yeni bir metot oluyor, ama kimse fark etmiyor. #[\Override] bu sessiz kopukluğu gürültülü bir hataya çeviriyor.
json_validate()
Bir metnin geçerli JSON olup olmadığını öğrenmek için bugüne kadar json_decode() çağırıp sonucu kontrol ediyorduk — yani tüm yapıyı belleğe kurup atıyorduk. 8.3, yalnızca doğrulama yapan json_validate() fonksiyonunu getiriyor.
if (json_validate($gelenVeri)) {
$decoded = json_decode($gelenVeri, true);
// işle
} else {
// geçersiz JSON
}
Büyük yükleri kabul eden uçlarda, geçersiz veriyi belleğe hiç açmadan elemek güzel bir kazanç. Özellikle webhook alıcıları ve toplu veri işleyen uçlar için anlamlı; test ettiğimde yalnızca doğrulama için json_decode çağırmaya kıyasla bellek kullanımı gözle görülür şekilde düşüyor.
Dinamik sabit erişimi
Küçük ama beklenen bir ekleme: artık bir sınıf sabitine değişkenle erişebiliyorsunuz:
$ad = 'BASARILI';
echo HttpDurum::{$ad};
Özelliklere ve metotlara çoktan yapabildiğimiz şeyi sabitlere de yapabilmek, dildeki bir asimetriyi gideriyor. Pratik kullanım senaryosu: bir yapılandırma dosyasından veya veritabanından sabit adı alıp dinamik olarak erişmek. Daha önce bunun için constant() veya reflection kullanıyordunuz; artık doğrudan sözdizimi var.
Bu sürümden çıkardığım
8.3’te göz kamaştıran bir özellik yok; ama olgun bir dilin nasıl yaşlandığını gösteriyor. Yeni sürümler her zaman büyük paradigma değişiklikleri getirmek zorunda değil. Çoğu zaman asıl değer, dilin kendi içindeki küçük tutarsızlıkları sessizce kapatmasında.
Tipli sabitler ve #[\Override], geçen yıllarda elle ya da yorum satırıyla koruduğum kuralları dilin kendisine devrediyor. Bir kuralı insan disiplinine bırakmak ile derleyiciye bırakmak arasındaki fark: birincisi yorulabiliyor, ikincisi yorulmuyor.
Sürüm çıkınca önce bu ikisini günlük koda almayı planlıyorum. json_validate() ise önümüzdeki webhook projesinde hemen işe yarayacak.
PHP’nin son birkaç sürümüne bakınca bir örüntü görüyorum: 8.0 union types ve match ile büyük bir adım attı, 8.1 readonly ve enum ile modellemeyi güçlendirdi, 8.2 readonly sınıflarıyla bunu tamamladı, 8.3 ise küçük tutarsızlıkları kapattı. Her sürüm bir öncekinin üstüne inşa ediyor ve dilin bütünlüğü giderek artıyor. Büyük paradigma değişiklikleri olmadan da bir dil olgunlaşabilir; PHP bunu gösteriyor. On yıl önceki PHP ile bugünkü PHP aynı ismi taşıyan farklı araçlar.