# PHP 7.4 ile gelen typed properties ve ok fonksiyonları

> PHP 7.4 Kasım 2019'da yayınlandı. Typed properties ve arrow function'lar, dilin tip sistemini ve sözdizimini önemli ölçüde güçlendiriyor.

- Yayın: 2019-12-01
- Kategori: Diller
- Etiketler: PHP
- Okuma süresi: 3 dk okuma
- Kaynak: https://www.muhammetsafak.com.tr/blog/php-7-4-ile-gelen-typed-properties-ve-ok-fonksiyonlari/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
PHP 7.4, Kasım 2019'da kararlı sürüm olarak yayınlandı. 7.x serisinin bu son büyük sürümünü sabırsızlıkla bekliyordum — iki özellik için: typed properties ve arrow function'lar. Birkaç haftadır gerçek kod yazarken kullanıyorum; izlenimlerimi paylaşmak istiyorum.

## Typed properties: sınıf özelliklerine tip

PHP 7.3 ve öncesinde bir sınıf özelliğinin (class property) tipini belirtmenin dil seviyesinde resmi bir yolu yoktu. Docblock ile `@var string` yazabilirdiniz ama bu yalnızca IDE ipucu ve dokümantasyon içindi — runtime'da bir etkisi yoktu.

PHP 7.4 ile artık şunu yapabiliyoruz:

```php
<?php

class User
{
    public int $id;
    public string $name;
    public string $email;
    public ?string $phone = null;
    public DateTimeImmutable $createdAt;
}
```

Bu tip bildirimleri runtime'da zorunlu tutuluyor. `$user->id = 'metin'` demeye çalışırsanız `TypeError` alırsınız. Bu, [PHP 7.0 ile gelen parametre ve dönüş tipi bildirimlerinin](/blog/php-7-de-skaler-tip-bildirimleri-ve-donus-tipleri) sınıf özelliklerine genişletilmesi.

### Nullable ve varsayılan değerler

`?string` gibi nullable tip kullanabilirsiniz. Ama şunu bilmek önemli: tipli bir özellik `null` değer taşıyabilmesi için ya nullable (`?T`) tanımlanmalı ya da bir varsayılan değer atanmalı. Aksi hâlde başlatılmamış bir özelliğe erişmek `Error` fırlatıyor:

```php
<?php

class Product
{
    public string $name; // başlatılmadan okunursa: Error
    public ?string $description = null; // güvenle okunabilir
    public float $price = 0.0;
}

$p = new Product();
// echo $p->name; // Fatal error: Typed property not initialized

$p->name = 'Kalem';
echo $p->name; // "Kalem"
```

Bu davranışı başta garip buldum. Ama aslında bir güvence: bir nesneyi oluştururken hangi özellikleri başlatmanız gerektiğini derleme anında değil, çalışma anında açıkça anlıyorsunuz. Constructor injection alışkanlığıyla birleşince bu sorunu yaşamıyorsunuz:

```php
<?php

class User
{
    public function __construct(
        public int $id,
        public string $name,
        public string $email,
        public ?string $phone = null
    ) {}
}
```

Burada PHP 7.4'te constructor promotion henüz yok (bu PHP 8.0 ile gelecek), ama constructor'da açıkça atama yaparak aynı güvenceyi sağlayabilirsiniz.

### Value object'ler için mükemmel

Tipli özellikler en çok değer nesnelerinde değer katıyor. Bir para birimi, adres veya koordinat gibi yapıları temsil eden sınıflarda özellik tiplerinin açık olması, yanlış kullanımı erkenden yakalıyor:

```php
<?php

class Money
{
    public int $amount;   // kuruş cinsinden
    public string $currency;

    public function __construct(int $amount, string $currency)
    {
        $this->amount = $amount;
        $this->currency = $currency;
    }
}
```

### Docblock'tan gerçek tipe geçişin getirisi

Typed properties öncesinde `@var` docblock'u yazmak bir alışkanlıktı, ama bunun yanlış girilmesini ya da zamanla güncellenmemesini engelleyen hiçbir şey yoktu. Kodun `@var int` diyip özelliğe string atanmış olduğu durumları birden fazla kez yaşadım. Dil seviyesinde tip bildirimi bu tutarsızlığı imkânsız kılıyor; docblock artık enforced bir belge, keyfi bir yorum değil.

## Arrow Functions

PHP'nin closure sözdizimi her zaman biraz kalabalık oldu:

```php
<?php

$multiplier = 3;
$result = array_map(function ($n) use ($multiplier) {
    return $n * $multiplier;
}, [1, 2, 3, 4, 5]);
```

`use ($multiplier)` satırı dış kapsamdan değişken yakalamak için gerekli — ama dikkat dağıtıcı. PHP 7.4'ün arrow function sözdizimi [bunu](/blog/phpde-closure-ve-use-ile-degisken-yakalama) sadeleştiriyor:

```php
<?php

$multiplier = 3;
$result = array_map(fn($n) => $n * $multiplier, [1, 2, 3, 4, 5]);
```

`fn` anahtar kelimesiyle yazılan fonksiyonlar dış kapsamı **otomatik olarak** yakalıyor; `use` gerekmez. `return` de yazmak gerekmiyor — tek ifade otomatik döndürülüyor.

Karmaşık dönüştürme zincirlerinde bu gerçekten fark yaratıyor:

```php
<?php

$aktifKullaniciAdalari = array_map(
    fn($user) => $user->name,
    array_filter($users, fn($user) => $user->active)
);
```

### Sınır: tek ifade

Ok fonksiyonları yalnızca tek bir ifade içerebiliyor. Birden fazla satır gerekiyorsa klasik `function` + `use` sözdizimi hâlâ yerinde. Bu sınır bazen can sıkıcı; özellikle bir koşul ya da ara değişken gereken durumlarda ok fonksiyonunu kullanamıyorsunuz. Ama bu kısıt kasıtlı: tek ifadelik zorunluluk, ok fonksiyonunu gerçekten kısa ve odaklı tutuyor. Uzun bir fonksiyon yazmak istiyorsanız bunu kasıtlı olarak eski sözdizimle yapmanız gerekiyor; bu da bir tür tasarım kararı.

## 7.x serisinin kapanışı

PHP 7.4, 7.x ailesinin son büyük sürümü. Typed properties ve arrow function'lar, PHP'nin tip sistemini ve fonksiyonel programlama kalıplarını güçlendiren eklemeler. 8.0 çok daha büyük bir sıçrama vaat ediyor — JIT derleyici, union types, match expression. Ama o köprüyü gelince geçeceğiz.

Şimdilik 7.4, production'da kullanmaktan çekinmeyeceğim, olgun ve değer katan bir sürüm.
