aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Web Geliştirme

PHP 8.3 Yenilikleri: Typed Constants ve json_validate

PHP 8.3, 23 Kasım 2023'te yayımlandı ve dile büyük bir devrim getirmekten çok, günlük geliştirme hayatını rahatlatan onlarca pratik iyileştirme sundu. Tip güvenliğini artıran typed class constants, JSON'u verimli doğrulayan json_validate(), kalıtım hatalarını derleme anında yakalayan #[\Override] niteliği ve sessizce gelen performans kazanımları bunların başında geliyor. Bu yazıda en çok işine yarayacak yenilikleri gerçek kod örnekleriyle inceliyoruz.

Typed class constants: sabitler artık tip güvenli

PHP'de sabitler uzun süredir tip bildirimi kabul etmiyordu. Bir alt sınıf, üst sınıftan miras aldığı bir sabiti yanlış tipte ezebiliyor ve bu hata ancak çalışma zamanında, en kötü ihtimalle production'da fark ediliyordu. PHP 8.3 ile sınıf, arayüz, trait ve enum sabitlerine tip bildirebiliyorsun.

interface Renkli
{
    const string VARSAYILAN = 'mavi';
}

class Kart implements Renkli
{
    // Hata: tip uyuşmuyor (string bekleniyor, int verildi)
    // const string VARSAYILAN = 0xFF;
    const string VARSAYILAN = 'kirmizi';
}

Burada önemli ayrıntı şu: alt sınıf sabiti, üst sınıftaki tiple uyumlu olmak zorundadır. Bir sabite int tipi verdiysen, miras alan sınıf onu string yapamaz. Bu, büyük kod tabanlarında sözleşmeleri (contract) çok daha güvenli hale getirir.

json_validate(): geçerliliği boşa bellek harcamadan kontrol et

Önceden bir metnin geçerli JSON olup olmadığını anlamak için tek pratik yöntem json_decode() çağırıp hata olup olmadığına bakmaktı. Ama bu, yalnızca doğrulamak isterken bile koca bir PHP veri yapısını bellekte oluşturuyordu. json_validate() tam olarak bu israfı çözer: ayrıştırır ama nesne kurmaz, sadece geçerli olup olmadığını söyler.

$ham = '{"ad":"Aslain","diller":["tr","en","de"]}';

if (json_validate($ham)) {
    $veri = json_decode($ham, true);
    // güvenle işle
} else {
    // hatalı gövde — 400 dön
}

Bu fonksiyon özellikle webhook gövdelerini, API isteklerini veya kullanıcıdan gelen büyük JSON yüklerini sadece "geçerli mi?" diye süzdüğün durumlarda anlamlı bir bellek ve hız avantajı sağlar. İçeriği gerçekten kullanacaksan yine json_decode() çağırırsın.

#[\Override] niteliği: ezmeyi derleyiciye doğrulat

Bir metodu üst sınıftan ezdiğini düşünüyorsun ama isimde küçük bir yazım hatası var; sonuç olarak ezmek yerine yeni bir metot tanımlamış oluyorsun ve hata sessizce kayboluyor. PHP 8.3'ün #[\Override] niteliği bu sınıf hataları ortadan kaldırır: metodun gerçekten bir üst tipten geldiğini bildirirsin, gelmiyorsa PHP fatal error verir.

class TemelKuyruk
{
    public function isle(): void {}
}

class RedisKuyruk extends TemelKuyruk
{
    #[\Override]
    public function isle(): void
    {
        // gerçekten ezdiğimiz garanti
    }
}

Bu nitelik özellikle arayüz uygulayan ya da derin kalıtım zincirleri olan kodda paha biçilmezdir. Üst sınıf metodun adını değiştirdiğinde, #[\Override] taşıyan alt sınıf anında çığlık atar ve sessiz bir bug'ı baştan engeller.

Dynamic class constant fetch ve yeni string yardımcıları

PHP 8.3 öncesinde bir sabitin adını değişkende tutup dinamik erişmek için constant() gibi dolambaçlı yollar gerekiyordu. Artık doğrudan süslü parantez sözdizimiyle erişebiliyorsun:

class Durum
{
    const AKTIF = 'aktif';
    const PASIF = 'pasif';
}

$alan = 'AKTIF';
echo Durum::{$alan}; // "aktif"

Ayrıca dize üretimi için iki küçük ama kullanışlı fonksiyon geldi: str_increment() ve str_decrement(). Bunlar alfanümerik dizeleri tıpkı bir araç plakası ya da seri numarası gibi mantıklı şekilde artırıp azaltır:

echo str_increment('Az');  // "Ba"
echo str_increment('A9');  // "B0"
echo str_decrement('B0');  // "A9"

Readonly klonlama ve Randomizer eklentileri

PHP 8.2'de gelen readonly özellikler güçlüydü ama bir kısıtları vardı: klonlarken değerini değiştiremiyordun. PHP 8.3 bunu çözdü; artık __clone() içinde bir readonly özelliği yeniden değer atayabiliyorsun. Bu, değiştirilemez (immutable) nesnelerin "with" tarzı kopyalarını üretmeyi çok daha temiz hale getirir.

final class Para
{
    public function __construct(
        public readonly int $kurus,
    ) {}

    public function __clone(): void
    {
        // klon sırasında yeniden atamaya izin var
    }
}

Rastgelelik tarafında Random\Randomizer sınıfına yeni metotlar eklendi: getFloat(), nextFloat() ve getBytesFromString(). Bunlar belirli bir alfabeden rastgele dize üretmek (örneğin parola, token veya kupon kodu) ya da kontrollü aralıkta float üretmek için tek satırlık, sapma içermeyen çözümler sunar.

Performans ve diğer küçük dokunuşlar

PHP 8.3 baş döndürücü bir hız sıçraması iddia etmez, ama JIT ve motor seviyesindeki iyileştirmeler tipik web yüklerinde kararlı, ölçülebilir kazançlar getirir. Bunun yanında dikkat çeken birkaç başlık daha var:

  • Yığın taşması koruması: zend.max_allowed_stack_size ile derin/sonsuz özyinelemeler artık segfault yerine düzgün bir hatayla durdurulabilir.
  • Daha isabetli Date/Time istisnaları: tarih sınıfları artık genel Exception yerine DateMalformedStringException gibi spesifik istisnalar fırlatır.
  • DateTime::createFromTimestamp(): bir zaman damgasından doğrudan, okunabilir biçimde tarih nesnesi üretmek için yeni statik metot.
  • Anonim readonly sınıflar: artık new readonly class { ... } yazabiliyorsun.

Pratik tavsiye: yeni bir projeye başlıyorsan doğrudan PHP 8.3 (veya daha üstü) seç. Mevcut bir Laravel ya da klasik PHP projesinde ise önce composer.json'daki sürüm kısıtını yükselt, ardından test paketini çalıştır; 8.3 büyük ölçüde geriye dönük uyumlu olduğu için geçiş genelde sancısızdır.

Sık Sorulan Sorular

PHP 8.2'den 8.3'e geçiş zor mu?

Çoğu durumda hayır. PHP 8.3 büyük geriye dönük uyumsuzluk getirmez; başlıca yeni özellikler kod eklemeye yöneliktir. Yine de üretime almadan önce otomatik testleri çalıştırmak ve kullandığın paketlerin 8.3 desteğini doğrulamak en sağlıklısıdır.

json_validate() her zaman json_decode()'dan hızlı mıdır?

Avantajı asıl bellek tarafındadır: json_validate() PHP veri yapısı kurmaz, bu yüzden büyük yüklerde daha az bellek tüketir. Ama veriyi gerçekten kullanacaksan ardından yine json_decode() çağırırsın; o zaman iki çağrı yapmak yerine doğrudan decode edip hata kontrolü yapmak daha mantıklı olabilir.

Typed constants eski koddaki sabitleri bozar mı?

Hayır. Tip bildirimi opsiyoneldir; mevcut tipsiz sabitlerin aynen çalışmaya devam eder. Tipi sadece güvence istediğin yerlerde, kademeli olarak ekleyebilirsin.

PHP altyapını modernleştirmek mi istiyorsun? Laravel veya saf PHP projelerinde 8.3'e geçiş, tip güvenliği ve performans denetimi için birlikte çalışalım. Benimle iletişime geç ve projeni konuşalım.

Bu kategorideki tüm yazılar →

Devamı için