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

PHP 8.0'a hazırlık: union types, match, named arguments

PHP 8.0 henüz çıkmadı ama RFC'ler ve beta sürümleri okunabilir. Üç önemli özelliği şimdiden anlamak için notlarımı paylaşıyorum.


PHP 8.0 bu ay çıkacak. Beta sürecini takip ettim, RFC’leri okudum, bir geliştirme ortamında denedim. Resmi sürüm gelmeden önce hazırlanmak için pratiğe en doğrudan dokunan üç özelliği not etmek istedim: union types, match ifadesi ve named arguments.

Bu yazı “yolda” çerçevesinde: şu an yazdığınız kod PHP 8.0’da nasıl görünebilir, hangi alışkanlıkları değiştirmek gerekiyor, nelere hazırlanmalısınız.

Union Types

PHP 7.4 ile gelen typed properties tip sistemini sınıf düzeyine taşıdı. PHP 8.0’da fonksiyon imzaları birden fazla tip kabul edebilecek:

// PHP 7.4 — tek tip
function processInput(string $value): string
{
    return strtoupper($value);
}

// PHP 8.0 — birleşik tip
function processInput(int|string $value): int|string
{
    if (is_int($value)) {
        return $value * 2;
    }
    return strtoupper($value);
}

Bu özellik gerçek hayatta nasıl görünüyor? Bugün şöyle bir kod yaygın:

/**
 * @param int|string $id
 * @return User|null
 */
public function findUser($id): ?User
{
    // ...
}

PHP 8.0’da PHPDoc gerekmiyor:

public function findUser(int|string $id): ?User
{
    // ...
}

?User sözdizimi (User|null kısaltması) zaten var; bu sözdizimi bunu genelleştiriyor.

Dikkat edilmesi gereken nokta: union type kullanmak her zaman iyi tasarım değil. int|string kabul eden bir fonksiyon büyük ihtimalle iki farklı davranış barındırıyor; bu ayrımı iki fonksiyona bölmek daha temiz olabilir. Ama bir API yanıtı ya da dış kaynak ayrıştırması gibi gerçekten belirsiz giriş durumlarında çok değerli.

Bir de şunu söylemek isterim: union type’lar PHPStan, Psalm gibi statik analiz araçlarıyla birlikte kullanıldığında en çok değer yaratıyor. Tip bildiriminiz makineye söylüyor, araç da her çağrı noktasını kontrol ediyor. PHPDoc yorumları da bunu yapabiliyordu ama tip bildirimi çalışma zamanında da geçerliydi; bu fark önemli.

match İfadesi

switch PHP’nin en eski yapılarından biri ve birkaç tuzak içeriyor: break unutmak, gevşek karşılaştırma (==), ifade değil deyim olması. match bunları düzeltiyor.

// switch — katı karşılaştırma yok, break gerekli
$status = 2;
$label = '';
switch ($status) {
    case 1:
        $label = 'Bekliyor';
        break;
    case 2:
        $label = 'İşleniyor';
        break;
    case 3:
        $label = 'Tamamlandı';
        break;
    default:
        $label = 'Bilinmiyor';
}

// match — katı karşılaştırma, ifade döner, break yok
$label = match($status) {
    1       => 'Bekliyor',
    2       => 'İşleniyor',
    3       => 'Tamamlandı',
    default => 'Bilinmiyor',
};

match bir expression; değer döndürüyor, doğrudan atama ya da return içinde kullanılabiliyor. Katı tip karşılaştırması yapıyor (===), bu PHP’de switch’in sessizce yaptığı hatalardan birini ortadan kaldırıyor.

Birden fazla koşul aynı değere yönleniyorsa virgülle yazılabiliyor:

$type = match(true) {
    $score >= 90         => 'A',
    $score >= 75, $score >= 70 => 'B',
    $score >= 60         => 'C',
    default              => 'F',
};

match’in küçük ama önemli bir davranışı: eşleşme bulunmazsa ve default kolu yoksa UnhandledMatchError fırlatıyor. switch’te bu durum sessizce geçilir ve değişken boş kalır. match bu gizli hatayı görünür kılıyor — çoğu zaman istediğiniz davranış bu.

Named Arguments

PHP fonksiyonlarına argümanları sırayla geçiriyorsunuz. Uzun parametre listelerinde hangi değerin hangi parametreye gittiği okunaksız hale geliyor. İsimli argümanlar bunu çözüyor:

// Sıra bazlı — üçüncü parametre ne?
array_slice($array, 0, true);

// İsimli — net
array_slice(array: $array, offset: 0, preserve_keys: true);

Kendi yazdığınız fonksiyonlarda da çalışıyor:

function createUser(
    string $name,
    string $email,
    string $role = 'user',
    bool   $active = true
): User {
    // ...
}

// İsteğe bağlı parametreler için özellikle değerli
$user = createUser(
    name: 'Ahmet Yılmaz',
    email: '[email protected]',
    active: false,  // role atlandı, active geçildi
);

Bu özellik parametre sırası bağımlılığını ortadan kaldırıyor. Varsayılan değerli parametreler arasında seçici olarak atlamak artık mümkün.

Bir kırılma noktasını da eklemeliyim: named arguments, parametre adını sözleşmenin bir parçası haline getiriyor. Bir kütüphane yazdıysanız ve parametre adını değiştirirseniz, named argument kullanan her çağrı kırılıyor. Bu, kütüphane yazarları için önemli bir tasarım kararı.

Hazırlık için ne yapmalı?

PHP 8.0 geriye dönük uyumluluğu büyük ölçüde koruyor, ama bazı breaking change’ler var. En önemlileri:

  • Tip gevşekliğine dayanan bazı karşılaştırmalar match ile farklı davranacak.
  • Kullanılmayan fonksiyon parametreleri için yeni uyarılar.
  • create_function kaldırıldı.

Mevcut projelerde bir geliştirme ortamı açıp php -d error_reporting=E_ALL ile testleri çalıştırmak, kırılma noktalarını bulmak için en hızlı yol.


PHP 8.0 küçük bir güncelleme değil. JIT derleyici de dahil olmak üzere büyük değişiklikler geliyor; ama günlük kod yazımına en çok dokunan bu üç özellik. Hazır olmak için kodu şimdiden okumak yeterli — sürüm çıkınca yeni imzaları doğal hissedeceksiniz.

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