PHP 7'de skaler tip bildirimleri ve dönüş tipleri
PHP 7 ile gelen skaler tip bildirimleri ve dönüş tipi tanımlamalarını pratikte nasıl kullandığımı anlatıyorum.
PHP 7’ye geçişin üzerinden birkaç hafta geçti. Performans artışı zaten herkesin gündemindeydi, ama benim için asıl çekici olan özellikler dil tarafındaydı: skaler tip bildirimleri ve dönüş tipleri. Bunları projelerimde denemeye başlayınca fonksiyon imzalarının ne kadar açıklayıcı hale geldiğini fark ettim.
Bu yazıda bu iki özelliği nasıl kullandığımı, strict_types modunun ne fark yarattığını ve dikkat ettiğim noktaları paylaşıyorum.
Skaler tip bildirimleri nedir?
PHP 5’ten beri sınıf adı ve dizi (array) için tür bildirimi yapılabiliyordu. PHP 7 ile birlikte buna int, float, string ve bool gibi skaler tipler de eklendi.
<?php
function toplam(int $a, int $b): int
{
return $a + $b;
}
echo toplam(3, 5); // 8
Yukarıdaki fonksiyonu PHP 5’te yazarken parametre tipi için docblock eklemekle yetinirdim. Artık bunu doğrudan imzaya yazabiliyorum; hem IDE desteği iyileşiyor hem de kod okunduğunda ne beklediği hemen anlaşılıyor.
strict_types ile zorlayıcı mod
PHP, varsayılan olarak type coercion yapar. Yani "5" gönderirseniz, int bekleyen bir fonksiyon bunu sessizce 5’e çevirir. Bu davranış zaman zaman kullanışlı, çoğu zaman ise tehlikeli.
Dosyanın en başına şunu ekleyince bu esneklik ortadan kalkıyor:
<?php
declare(strict_types=1);
function carpim(int $a, int $b): int
{
return $a * $b;
}
carpim(4, "3"); // TypeError fırlatır
strict_types=1 bildirimi yalnızca bulunduğu dosyayı etkiliyor, tüm uygulamayı değil. Bu önemli bir ayrıntı: çağrıyı yapan dosyada strict_types açık olsa bile, fonksiyonun tanımlı olduğu dosyada kapalıysa dönüşüm yine gerçekleşebilir.
Ben yeni yazdığım tüm dosyalara bu bildirimi eklemeyi alışkanlık haline getirdim. Başta alışmak biraz vakit aldı; özellikle kullanıcıdan gelen form verisi her zaman string olarak geliyor, onu açıkça dönüştürmek gerekiyor. Ama bu, aslında iyi bir şey: kodun nerede dönüşüm yaptığını artık görüyorsunuz.
Dönüş tipi bildirimi
Fonksiyonun ne döndürdüğünü de imzaya yazabiliyorsunuz:
<?php
declare(strict_types=1);
function kullaniciBul(int $id): array
{
// veritabanından kullanıcı çek
return ['id' => $id, 'ad' => 'Ahmet'];
}
function aktifMi(int $id): bool
{
return $id > 0;
}
Özellikle bool döndüren fonksiyonlarda bu çok işe yarıyor. Eskiden docblock’a bakmadan “bu fonksiyon ne döndürüyor?” sorusunu cevaplamak için fonksiyon gövdesini okumak gerekiyordu.
void dönüş tipi hakkında bir not
PHP 7.0’da void dönüş tipi henüz yok — bu PHP 7.1 ile geliyor. Şimdilik yalnızca değer döndüren fonksiyonlara tip yazabiliyorsunuz.
Nullable tipler de henüz yok
Aynı şekilde, ?int sözdizimi de PHP 7.1’e kadar bekliyor. Eğer bir fonksiyon int ya da null döndürebiliyorsa, şimdilik dönüş tipi tanımlamadan bırakmak ya da docblock ile belgelemek gerekiyor.
<?php
// PHP 7.0'da nullable için geçici çözüm
// Dönüş tipi yazamıyoruz, docblock ile belgeliyoruz
/**
* @return int|null
*/
function sonKayitId()
{
// tablo boşsa null döner
return null;
}
Bu eksiklik can sıkıcı; ama 7.1’i bekleyebilirim. Şimdiden tip bildirimi yazmak alışkanlığını edinmek önemli.
Pratikte ne değişti?
Birkaç haftalık deneyime dayanarak şunu söyleyebilirim: Tip bildirimleri, fonksiyon imzasını bir sözleşmeye dönüştürüyor. Birlikte çalıştığım kişiye ya da ilerideki kendime “bu fonksiyona şu tipi ver, şu tipi al” demiş oluyorum. Hata mesajları da çok daha anlaşılır hale geldi; TypeError aldığınızda sorunun nerede olduğunu hemen anlıyorsunuz.
Öte yandan, mevcut kod tabanına toplu olarak tip eklemek çok temkinli yapılması gereken bir iş. Koşulsuz dönüşüme güvenen eski kodlar strict_types ile birlikte beklenmedik yerden patlayabiliyor. Yeni dosyalar için hemen kullanmak, mevcut dosyalar için dikkatli yaklaşmak mantıklı.
PHP 7 bu konuda beklediğimden daha kullanışlı bir adım atmış. Dilin bu yönde ilerlemesi sevindirici.