PHP Fonksiyonlar: Parametre, Dönüş Tipi ve Kapsam

PHP Fonksiyonlar: Parametre, Dönüş Tipi ve Kapsam

4 dakika okuma

Fonksiyon, tekrarlanan işi tek bir isim altında toplayan yapıdır. İyi tanımlanmış bir fonksiyon tek bir iş yapar, girdisini parametreden alır ve sonucunu döndürür. Dışarıdaki değişkenlere doğrudan dokunan fonksiyonlar test edilmesi ve takip edilmesi zor kod üretir. Aynı fonksiyon aynı girdilerle her çağrıldığında aynı sonucu veriyorsa, davranışı tahmin edilebilir olur ve hata ayıklama süresi belirgin biçimde kısalır.

Tanım ve tip bildirimi

Parametre ve dönüş tipleri bildirildiğinde hatalı kullanım çağrı anında ortaya çıkar. Dönüş tipi null olabiliyorsa soru işareti ile belirtilir:

PHP17 satır
declare(strict_types=1);

function kdvHesapla(float $tutar, float $oran = 0.20): float
{
    return round($tutar * (1 + $oran), 2);
}

function kullaniciBul(array $liste, int $id): ?array
{
    foreach ($liste as $k) {
        if ($k['id'] === $id) {
            return $k;
        }
    }

    return null;
}

Varsayılan ve isimli argümanlar

Varsayılan değeri olan parametreler listenin sonunda yer alır. PHP 8 ile gelen isimli argümanlar, çok parametreli fonksiyonlarda çağrının okunurluğunu artırır ve sıraya bağımlılığı kaldırır:

PHP7 satır
function rapor(string $baslik, bool $detay = false, string $format = 'html'): string
{
    // ...
    return $format;
}

rapor('Aylık özet', format: 'pdf');

Değişken sayıda argüman gerektiğinde üç nokta kullanılır. Bu yapı, dizi geçirmeye göre imzayı daha açık bırakır:

PHP6 satır
function topla(int ...$sayilar): int
{
    return array_sum($sayilar);
}

topla(1, 2, 3);

Değişken kapsamı

Fonksiyon içinde tanımlanan değişkenler dışarıdan görünmez, dışarıdaki değişkenler de otomatik olarak içeride kullanılamaz. Bu yalıtım kasıtlıdır ve global anahtar kelimesiyle delinmemelidir. İhtiyaç duyulan değer parametre olarak geçilir.

static ile tanımlanan yerel değişken çağrılar arasında değerini korur. Sayaç gibi sınırlı durumlarda işe yarar, ancak fonksiyonu duruma bağımlı hale getirdiği için dikkatli kullanılmalıdır:

PHP7 satır
function sayac(): int
{
    static $adet = 0;
    $adet++;

    return $adet;
}

Anonim fonksiyonlar ve ok fonksiyonları

Yalnızca bir yerde kullanılacak kısa mantık için isimlendirilmiş fonksiyon tanımlamaya gerek yoktur. Anonim fonksiyon dış kapsamdaki değişkeni use ile alır; ok fonksiyonu ise otomatik olarak yakalar ve tek ifadeyle sınırlıdır:

PHP8 satır
$limit = 1000;

$buyukler = array_filter($tutarlar, function (float $t) use ($limit): bool {
    return $t > $limit;
});

// aynı iş, ok fonksiyonuyla
$buyukler = array_filter($tutarlar, fn(float $t): bool => $t > $limit);

Referansla parametre

Parametreler varsayılan olarak değer kopyası şeklinde geçer. Değişkenin kendisini değiştirmek gerekiyorsa referans kullanılır, ancak bu durum çağıran tarafta beklenmedik sonuçlar doğurabileceği için nadiren tercih edilmelidir:

PHP6 satır
function siralaVeSay(array &$dizi): int
{
    sort($dizi);

    return count($dizi);
}

Fonksiyonu ne zaman bölmek gerekir?

Bir fonksiyonun uzunluğu tek başına ölçüt değildir. Bölme kararı için daha güvenilir işaret, fonksiyonun adının işini tam anlatamaz hale gelmesidir. Adında ve geçen bir fonksiyon genellikle iki iş yapıyordur.

İkinci işaret, parametre sayısının artmasıdır. Dörtten fazla parametre alan fonksiyonlarda çağrı tarafı okunmaz hale gelir. Bu durumda ilişkili parametreler tek bir diziye ya da nesneye taşınır.

PHP6 satır
// bölünmesi gereken imza
function kaydet(string $ad, string $eposta, string $sehir,
    string $telefon, bool $bulten, bool $onay): bool { /* ... */ }

// veriyi tek yapıda topla
function kaydet(array $kullanici): bool { /* ... */ }

Fonksiyon mu, sınıf metodu mu?

Girdisini parametreden alıp sonucunu döndüren, dış duruma bağlı olmayan işler için serbest fonksiyon yeterlidir. Ortak bir durumu paylaşan, birlikte anlam kazanan birden fazla işlem varsa sınıf metodu daha uygun olur.

Ayrımın pratik göstergesi şudur: aynı üç dört fonksiyon sürekli aynı parametreleri alıyorsa, o parametreler aslında bir nesnenin durumudur. Bu noktada fonksiyonları sınıfa taşımak imzaları da sadeleştirir:

PHP12 satır
// tekrar eden bağlantı parametresi
function kullaniciGetir(PDO $db, int $id): ?array { /* ... */ }
function kullaniciSil(PDO $db, int $id): bool { /* ... */ }

// durum sınıfa taşınır
final class KullaniciDeposu
{
    public function __construct(private PDO $db) {}

    public function getir(int $id): ?array { /* ... */ }
    public function sil(int $id): bool { /* ... */ }
}

Hata durumunda ne döndürmeli?

Bir fonksiyon beklenen sonucu üretemediğinde iki seçenek vardır: null döndürmek ya da istisna fırlatmak. Ayrım, durumun olağan olup olmamasına göre yapılır. Aranan kaydın bulunamaması olağandır ve null uygundur; veritabanı bağlantısının kurulamaması olağan değildir ve istisna gerektirir.

PHP15 satır
function kullaniciBul(PDO $db, int $id): ?array
{
    $stmt = $db->prepare('SELECT * FROM users WHERE id = ?');
    $stmt->execute([$id]);

    return $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
}

function kullaniciSil(PDO $db, int $id): void
{
    if ($id <= 0) {
        throw new InvalidArgumentException('Geçersiz kimlik');
    }
    // ...
}

Hata kodu döndüren fonksiyonlardan kaçınmak gerekir. Çağıran taraf dönüş değerini kontrol etmeyi unuttuğunda hata sessizce yutulur; istisna ise yakalanmadığında görünür olur.

Kontrol listesi

  • Her fonksiyon tek bir iş yapar ve adı bu işi anlatır.
  • Parametre ve dönüş tipleri bildirilir.
  • global anahtar kelimesi yerine parametre geçilir.
  • Uzun parametre listelerinde isimli argüman kullanılır.
  • Referanslı parametre yalnızca gerçekten gerekliyse tercih edilir.

PHP eğitim serisi

Bu yazı, temel sözdiziminden üretim ortamına kadar ilerleyen 25 bölümlük serinin bir parçası. Bölümler sırayla okunacak biçimde hazırlandı, ancak her biri tek başına da kullanılabilir.

Temeller

  1. Kurulum ve temel sözdizimi
  2. Döngüler ve akış kontrolü
  3. Diziler
  4. Fonksiyonlar (bu yazı)
  5. String fonksiyonları
  6. Süper globaller
  7. Form işleme
  8. Dosya işlemleri

Dilin ayrıntıları

  1. Tip sistemi ve strict_types
  2. Hata ve istisna yönetimi
  3. Düzenli ifadeler
  4. Tarih ve saat işlemleri

Nesne yönelimli PHP

  1. Sınıf ve nesne
  2. Kalıtım, arayüz ve trait
  3. Statik üyeler, sabitler ve enum
  4. Namespace, Composer ve autoload

Veri ve güvenlik

  1. PDO ile veritabanı işlemleri
  2. Oturum yönetimi ve kimlik doğrulama
  3. Güvenli çıktı ve XSS
  4. JSON ile veri değişimi

Dış dünya ve üretim

  1. cURL ile dış API çağırma
  2. Kendi REST API'ni yazmak
  3. PHPUnit ile birim test
  4. Hata ayıklama ve performans ölçümü
  5. Üretime alma ve güvenlik

Yorumlar

Bu form reCAPTCHA ile korunur; Google Gizlilik Politikası ve Hizmet Şartları geçerlidir.

İlk yorumu sen yap.

İlgili Yazılar