---
title: Fonksiyonlar
source: 'https://academia.sh/tr/kurslar/php-temelleri/fonksiyonlar'
course: 'PHP Temelleri'
language: tr
updated: '2026-10-21T05:03:33+00:00'
license: 'CC BY-SA 4.0'
objectives:
    - 'Kullanıcı fonksiyonuna verilen fazla argümanın sinyalsiz yutulduğunu, yerleşik fonksiyonlarda ise reddedildiğini ölçerek gösterir'
    - 'Eksik, bilinmeyen ve çakışan adlandırılmış argümanların hangi hatayı verdiğini ayırt eder'
    - 'Varsayılan değer ile static değişkenin çağrılar arasındaki davranış farkını doğrular'
    - '...$x ile fazlalığın görünür kılınabileceğini ve dönüş tipinin zorlama davranışını sayarak gösterir'
---

# Fonksiyonlar

PHP fonksiyonlarında argüman ve dönüş davranışı: fazla argümanın sinyalsiz yutulması, eksik ve bilinmeyen argüman hataları, varsayılan değer ve static, değer ve referans geçişi, dönüş tipi ve ...$x ile fazlalığın görünür kılınması.

Denetim Akışı dersi, karşılıksız bir dalın `switch`'te sessizce geçtiğini, `match`'te ise yürütmeyi durdurduğunu ölçtü. Bu ders aynı soruyu çağrılara soruyor: bir fonksiyona beklenenden fazla argüman verildiğinde, fazlalık nereye gidiyor, eksik verildiğinde ne oluyor? Bu dersin ölçü sınıfı sessizdir: kullanıcının yazdığı bir fonksiyona fazla verilen argüman, hiçbir bildirim üretmeden yok sayılır.

PHP'de `function` anahtar sözcüğüyle bildirilen fonksiyon, `return` ile bir değer döndürür; parametrelerine tip ve varsayılan değer yazılabilir. Programlama Temelleri kursunda (M01/K02) fonksiyon kavramı kurulmuştu; burada yalnız PHP'nin bu kavrama nasıl davrandığı ölçülüyor. Bir değişikliğin çağırana ve başkasına görünüp görünmediği sorusu M11/K03'te nesneler için ayrıca ölçülmüştü; bu derste yalnız skaler ve dizi değerleri için gerektiği kadar anılıyor.

## Fazla Argüman

Kullanıcı fonksiyonuna parametre sayısından fazla argüman verilirse PHP fazlayı hata saymaz: fonksiyon yine çalışır ve fazla argümanlar yok sayılır. Yerleşik fonksiyonlar bu konuda katıdır. Aşağıdaki dosya iki parametreli bir fonksiyona üç argüman verir ve aynı şeyi yerleşik `strlen()` ile dener; hata işleyicisi bir sayaç tutar.

```php
<?php
// fazla.php — kullanici fonksiyonu fazla argumani yutar, yerlesik reddeder
$bildirim = 0;
set_error_handler(function (int $seviye) use (&$bildirim): bool {
    $bildirim++;
    return true;
});

function iki_topla($a, $b)
{
    return $a + $b;
}

echo 'iki_topla(1, 2, 3):  ', iki_topla(1, 2, 3), "\n";

try {
    $uzunluk = strlen('abc', 'x');
    echo 'strlen(abc, x):     ', $uzunluk, "\n";
} catch (ArgumentCountError $hata) {
    echo 'strlen(abc, x):     ', get_class($hata), "\n";
}
echo 'bildirim: ', $bildirim, "\n";
```

```
iki_topla(1, 2, 3):  3
strlen(abc, x):     ArgumentCountError
bildirim: 0
```

**KN43.** `iki_topla(1, 2, 3)` ifadesi `3` döndürdü, yani üçüncü argüman toplamda yer almadı ve bunun için hiçbir şey söylenmedi: sayaç sıfır kaldı. Aynı fazlalığa yerleşik `strlen()` bir `ArgumentCountError` ile karşılık verdi. Bu asimetri bir tasarım kararıdır: kullanıcı fonksiyonlarında fazla argümanın hata sayılmaması, bir fonksiyonun sonradan fazladan bir isteğe bağlı parametre kazanabilmesine izin verir. Bedeli, bir çağrıdaki yazım hatasının yutulabilmesidir.

## Eksik ve Bilinmeyen Argüman

Fazlalığın aksine eksik argüman bir hatadır: zorunlu bir parametre doldurulmazsa `ArgumentCountError` fırlar. PHP, argümanların konumla verilmesinin yanında ada göre de verilmesine izin verir (adlandırılmış argüman, named argument). Aşağıdaki dosya beş çağrı yapar: eksik, tam, adlandırılmış, bilinmeyen adlı ve zaten konumla doldurulmuş bir parametreyi yeniden adlandıran bir çağrı.

```php
<?php
// eksik.php — eksik argumani ArgumentCountError, bilinmeyen adi Error reddeder
function selamla(string $ad, string $unvan = 'bay'): string
{
    return $unvan . ' ' . $ad;
}

$cagrilar = [
    'selamla()'                      => fn() => selamla(),
    "selamla('Ada')"                 => fn() => selamla('Ada'),
    "selamla(unvan: 'dr', ad: 'Ada')" => fn() => selamla(unvan: 'dr', ad: 'Ada'),
    "selamla('Ada', soyad: 'X')"     => fn() => selamla('Ada', soyad: 'X'),
    "selamla('Ada', ad: 'Ece')"      => fn() => selamla('Ada', ad: 'Ece'),
];
foreach ($cagrilar as $ad => $cagri) {
    try {
        $yazi = var_export($cagri(), true);
    } catch (Error $hata) {
        $yazi = get_class($hata);
    }
    printf("%-34s%s\n", $ad, $yazi);
}
```

```
selamla()                         ArgumentCountError
selamla('Ada')                    'bay Ada'
selamla(unvan: 'dr', ad: 'Ada')   'dr Ada'
selamla('Ada', soyad: 'X')        Error
selamla('Ada', ad: 'Ece')         Error
```

**KN44.** Eksik argüman `ArgumentCountError` verdi. Varsayılan değeri olan `$unvan` atlanınca `'bay Ada'` üretildi. Adlandırılmış argümanlar sıradan bağımsız çalıştı: `unvan` önce yazıldığı hâlde `'dr Ada'` çıktı. Fonksiyonda tanımlı olmayan `soyad` adı ve zaten konumla doldurulmuş `ad` parametresi birer `Error` fırlattı. Yani fazla konumlu argüman sessiz, fazla adlandırılmış argüman gürültülüdür; adlandırma, kullanıcıya fazla argümanın yutulmasından daha sıkı bir sözleşme verir.

## Varsayılan Değer ve static

Varsayılan değer her çağrıda yeniden hesaplanır; yani bir parametrenin varsayılanı olarak yazılan boş dizi, her çağrıda yeni bir boş dizidir ve önceki çağrının eklediği elemanları taşımaz. Bir fonksiyon içinde `static` ile bildirilen değişken ise çağrılar arasında yaşar. Aşağıdaki dosya iki davranışı yan yana koyar.

```php
<?php
// varsayilan.php — varsayilan her cagrida yenilenir, static cagrilar arasinda yasar
function ekle(int $eleman, array $liste = []): array
{
    $liste[] = $eleman;
    return $liste;
}

function say(): int
{
    static $sayac = 0;
    $sayac++;
    return $sayac;
}

echo 'ekle(1):  ', count(ekle(1)), "\n";
echo 'ekle(2):  ', count(ekle(2)), "\n";

say();
say();
echo 'say():    ', say(), "\n";
```

```
ekle(1):  1
ekle(2):  1
say():    3
```

**KN45.** `ekle` iki çağrıda da bir eleman döndürdü: varsayılan boş dizi her çağrıda yenilendi. `say` üçüncü çağrıda `3` verdi: `static` değişken fonksiyon her bittiğinde silinmedi. İkisi aynı ayrımı iki yönden gösterir: parametre ve yerel değişken çağrıya bağlıdır, `static` değişken fonksiyona bağlıdır. Hiçbiri bildirim üretmez.

## Değer ve Referans

PHP argümanları varsayılan olarak değerle geçirir: fonksiyon kendi kopyası üzerinde çalışır ve çağıranın değişkenine dokunmaz. Parametre `&` ile bildirilirse fonksiyon çağıranın değişkenini değiştirir. Aşağıdaki dosya aynı değişikliği iki bildirimle yapar ve çağıranın dizisini sayar.

```php
<?php
// deger.php — deger kopyalar, referans cagiranin degiskenini degistirir
function degerle(array $dizi, int $sayi): void
{
    $dizi[] = 99;
    $sayi++;
}

function referansla(array &$dizi, int &$sayi): void
{
    $dizi[] = 99;
    $sayi++;
}

$liste = [1, 2];
$n = 10;

degerle($liste, $n);
echo 'degerle:    ', count($liste), ' eleman, n: ', $n, "\n";

referansla($liste, $n);
echo 'referansla: ', count($liste), ' eleman, n: ', $n, "\n";
```

```
degerle:    2 eleman, n: 10
referansla: 3 eleman, n: 11
```

**KN46.** Değerle geçirilen çağrıdan sonra dizi iki eleman, sayı on kaldı: fonksiyon kopyayı değiştirdi. Referansla geçirilen çağrıdan sonra dizi üç eleman, sayı on bir oldu. Bu ayrımın nesneler için sonucu M11/K03'te ölçülmüştü; burada gözlenen, dil `&` yazılmadıkça bir değişikliğin çağırana görünmediğidir. Referans parametre, fonksiyonun imzasından okunur: çağrıda hiçbir işaret yoktur.

## Dönüş Değeri

`return` yazılmayan bir fonksiyon `null` döndürür. Dönüş tipi bildirilmişse PHP dönen değeri o tipe zorlar, tıpkı parametrelerde olduğu gibi: Değişkenler dersindeki zorlama kuralı burada da işler. Aşağıdaki dosya dönüş davranışını dört durumda gösterir.

```php
<?php
// donus.php — return yoksa null, donus tipi zorlar veya reddeder
function bos()
{
}

function sayiya(): int
{
    return '5';
}

function bozuk(): int
{
    return 'bes';
}

function bosluk(): void
{
}

echo 'bos():    ', var_export(bos(), true), "\n";
echo 'bosluk(): ', var_export(bosluk(), true), "\n";

$sonuc = sayiya();
echo 'sayiya(): ', var_export($sonuc, true), ' ', get_debug_type($sonuc), "\n";

try {
    bozuk();
} catch (TypeError $hata) {
    echo 'bozuk():  ', get_class($hata), "\n";
}
```

```
bos():    NULL
bosluk(): NULL
sayiya(): 5 int
bozuk():  TypeError
```

**KN47.** `return` olmayan fonksiyon `null` döndürdü, `void` bildirilmiş olan da. `: int` bildirimli fonksiyon `'5'` dizgisini sessizce `5`'e çevirdi; `'bes'` ise zorlanamadığı için `TypeError` verdi. Dönüş tipi bu yüzden parametre tipiyle aynı kuralı izler: sayısal dizgi zorlanır, değilse reddedilir.

## Fonksiyonun Tanımlandığı An

PHP fonksiyonu bir dosya yürütülmeye başlamadan önce tanıyabilir, ama her fonksiyon için değil. Dosyanın en üst düzeyinde koşulsuz bildirilen fonksiyon, dosya okunurken tanınır ve bildirimden önceki satırda çağrılabilir. Bir `if` bloğunun içinde bildirilen fonksiyon ise yalnız o blok yürütüldüğünde var olur. Hiç bildirilmemiş bir fonksiyonun çağrısı ise bir `Error` fırlatır. Aşağıdaki dosya üç durumu `function_exists()` ile ölçer.

```php
<?php
// tanim.php — ust duzey fonksiyon onceden bilinir, kosullu olan calisinca tanimlanir
echo 'onceden:  ', var_export(function_exists('ust_duzey'), true), "\n";
echo 'kosullu:  ', var_export(function_exists('kosullu'), true), "\n";
echo 'cagri:    ', ust_duzey(), "\n";

function ust_duzey(): string
{
    return 'calisti';
}

if (true) {
    function kosullu(): string
    {
        return 'x';
    }
}
echo 'sonra:    ', var_export(function_exists('kosullu'), true), "\n";

try {
    yok_boyle_bir_sey();
} catch (Error $hata) {
    echo 'tanimsiz: ', get_class($hata), "\n";
}
```

```
onceden:  true
kosullu:  false
cagri:    calisti
sonra:    true
tanimsiz: Error
```

**KN48.** Koşulsuz bildirilen `ust_duzey` bildirim satırından önce de vardı ve çağrı çalıştı. Koşullu bildirilen `kosullu` blok yürütülmeden önce yoktu, yürütüldükten sonra oldu. Tanımsız bir ad ise `Error` verdi, yani durdurur sınıfındadır. Sessiz olan, çağrının hangi satırda yapıldığına bağlı olarak aynı adın bir yerde çalışıp başka yerde çalışmamasıdır: fonksiyonun varlığı dosyanın yapısına, koşullu olanın varlığı yürütme sırasına bağlıdır.

## Kapanış ve Yakalanan Değişken

Anonim fonksiyon (closure) dış kapsamdaki değişkene kendiliğinden erişemez; `use` ile açıkça yakalaması gerekir. `use ($x)` değeri bildirim anında kopyalar, `use (&$x)` ise değişkenin kendisini bağlar. Ok fonksiyonu (arrow function) `fn` ise dış değişkeni oluşturulduğu anda değerle yakalar. Aşağıdaki dosya üç yakalama biçimini, yakalanan değişken sonradan değiştirildikten sonra çağırarak ölçer.

```php
<?php
// kapanis.php — use degeri yakalar, & degiskeni baglar, ok fonksiyonu olustugu andaki degeri alir
$x = 1;
$degerle = function () use ($x) {
    return $x;
};
$referansla = function () use (&$x) {
    return $x;
};
$ok = fn() => $x;

$x = 2;
echo 'use ($x):  ', $degerle(), "\n";
echo 'use (&$x): ', $referansla(), "\n";
echo 'fn:        ', $ok(), "\n";

$artir = fn() => $x++;
$artir();
echo 'fn icinde artirma sonrasi x: ', $x, "\n";
```

```
use ($x):  1
use (&$x): 2
fn:        1
fn icinde artirma sonrasi x: 2
```

**KN49.** `$x` iki yapıldıktan sonra değerle yakalayan iki biçim eski değeri, yani `1`'i gördü; yalnız `&` ile bağlanan `2`'yi gördü. Ok fonksiyonunun içindeki artırma dışarıdaki `$x`'i değiştirmedi: değişken ok fonksiyonuna kopya olarak girdi. Ayrım, değer ve referans geçişinin kapanışlardaki karşılığıdır ve bildirim üretmez: yanlış biçimi seçen kod hata vermez, eski bir değerle çalışır.

## Boş Değer Kabul Eden Parametre

Bir parametreye `null` verilebilmesi iki ayrı şeydir: parametrenin tipinin `null` kabul etmesi ve parametrenin atlanabilmesi. `?int $x` null kabul eder ama zorunludur; `?int $x = null` hem null kabul eder hem atlanabilir. Birleşik tip (`int|string`) ise gevşek kipte hangi tipe zorlanacağını bir sıraya göre seçer. Aşağıdaki dosya altı çağrıyı bir tabloda ölçer.

```php
<?php
// bos_deger.php — ?int zorunludur, = null atlanabilir, birlesik tip zorlama sirasini secer
function zorunlu(?int $x)
{
    return var_export($x, true);
}

function atlanabilir(?int $x = null)
{
    return var_export($x, true);
}

function birlesik(int|string $x)
{
    return get_debug_type($x);
}

$cagrilar = [
    'zorunlu(null)'      => fn() => zorunlu(null),
    'zorunlu()'          => fn() => zorunlu(),
    'atlanabilir()'      => fn() => atlanabilir(),
    "birlesik('5')"      => fn() => birlesik('5'),
    'birlesik(5.0)'      => fn() => birlesik(5.0),
    'birlesik([])'       => fn() => birlesik([]),
    'birlesik(true)'     => fn() => birlesik(true),
];
foreach ($cagrilar as $ad => $cagri) {
    try {
        $yazi = $cagri();
    } catch (Error $hata) {
        $yazi = get_class($hata);
    }
    printf("%-20s%s\n", $ad, $yazi);
}
```

```
zorunlu(null)       NULL
zorunlu()           ArgumentCountError
atlanabilir()       NULL
birlesik('5')       string
birlesik(5.0)       int
birlesik([])        TypeError
birlesik(true)      int
```

**KN50.** `zorunlu(null)` çalıştı ama `zorunlu()` `ArgumentCountError` verdi: `?` null kabul etmeyi sağlar, atlanabilirliği sağlamaz. `atlanabilir()` `NULL` döndürdü. Birleşik tipte tam eşleşen değer olduğu gibi kaldı; tam eşleşme yoksa PHP bir sıra izledi ve sonucu sessizce seçti; dizi gibi hiçbir üyeye çevrilemeyen değer ise `TypeError` verdi. Bu, tip bildirimi dersindeki gevşek kip gözleminin birleşik tiplerdeki karşılığıdır.

## Geri Çağrılan Fonksiyon

Bir fonksiyona argüman olarak verilen fonksiyon (geri çağrı, callback) çağıran tarafından, bildiriminin beklediğinden fazla argümanla çağrılabilir. Kullanıcı fonksiyonu bu fazlalığı yine sessizce yutar; yerleşik fonksiyon ise yutmaz. Aşağıdaki dosya `array_filter()`'ı iki argüman gönderen kipte, tek parametreli bir kapanışla çalıştırır ve aynı sınamayı yerleşik `strlen` ile `array_map()` üzerinden yapar.

```php
<?php
// geri_cagri.php — geri cagrilan kullanici fonksiyonu fazla argumani yutar, yerlesik yutmaz
$sayilar = [1, 2, 3, 4];

$tek_parametre = array_filter($sayilar, fn($v) => $v > 2, ARRAY_FILTER_USE_BOTH);
echo 'tek parametreli: ', implode(',', $tek_parametre), "\n";

$iki_parametre = array_filter($sayilar, fn($v, $k) => $k % 2 === 0, ARRAY_FILTER_USE_BOTH);
echo 'iki parametreli: ', implode(',', $iki_parametre), "\n";

try {
    $sonuc = array_map('strlen', ['a'], ['b']);
    echo 'strlen: ', count($sonuc), "\n";
} catch (ArgumentCountError $hata) {
    echo 'strlen: ', get_class($hata), "\n";
}
```

```
tek parametreli: 3,4
iki parametreli: 1,3
strlen: ArgumentCountError
```

**KN51.** İki argümanla çağrılan tek parametreli kapanış anahtarı hiç görmeden çalıştı ve `3,4` verdi. İki parametreli olan anahtarı kullandı ve çift indeksli iki elemanı, `1,3`'ü seçti. İki diziyle çağrılan `array_map()` ise `strlen`'e iki argüman gönderdi ve `ArgumentCountError` aldı. Aynı fazla argüman, geri çağrının türüne göre bir yerde sessiz, bir yerde durdurucu oldu.

## Sınırlayıcı Ölçüm

Kullanıcı fonksiyonundaki sessiz yutmanın sınırı, fazlalığı görünür kılmanın mümkün olmasıdır. İki yol vardır: `func_num_args()` fonksiyon içinde gerçekte kaç argüman verildiğini söyler; `...$x` sözdizimi ise kalan bütün argümanları bir dizide toplar ve fazlalık o dizinin uzunluğunda görünür. Aşağıdaki dosya üç yolu aynı çağrıyla ölçer.

```php
<?php
// gorunur.php — func_num_args ve ...$x fazlaligi gorunur kilar
function iki_topla($a, $b)
{
    return $a + $b;
}

function say_argumani($a, $b)
{
    return func_num_args();
}

function topla(int ...$sayilar): int
{
    return array_sum($sayilar);
}

function kac_tane(...$x): int
{
    return count($x);
}

echo 'iki_topla(1, 2, 3):    ', iki_topla(1, 2, 3), "\n";
echo 'say_argumani(1, 2, 3): ', say_argumani(1, 2, 3), "\n";
echo 'topla(1, 2, 3):        ', topla(1, 2, 3), "\n";
echo 'kac_tane(1, 2, 3):     ', kac_tane(1, 2, 3), "\n";
```

```
iki_topla(1, 2, 3):    3
say_argumani(1, 2, 3): 3
topla(1, 2, 3):        6
kac_tane(1, 2, 3):     3
```

**KN52.** `iki_topla` üçüncü argümanı yine yuttu ve `3` verdi. `func_num_args()` aynı çağrıda `3` saydı: yutulan argüman, fonksiyonun içinden ölçülebilir. `...$sayilar` ile yazılan fonksiyon üç sayıyı da topladı ve `6` verdi; `...$x` ise fazlalığı bir dizi olarak teslim etti ve `count` `3` söyledi. Sessiz sınıf bu yüzden kaçınılmaz değildir: fonksiyon yazarı, fazlalığın görünür olacağı bir imza seçebilir.

## Özet

- Fonksiyonların ölçü sınıfı sessizdir: kullanıcı fonksiyonuna verilen fazla konumlu argüman bildirim üretmeden yok sayılır, yerleşik fonksiyon ise `ArgumentCountError` fırlatır.
- Eksik zorunlu argüman `ArgumentCountError`, bilinmeyen ya da çakışan adlandırılmış argüman `Error` verir; adlandırma konumdan sıkıdır.
- Varsayılan değer her çağrıda yenilenir, `static` değişken çağrılar arasında yaşar.
- Argümanlar değerle geçer; `&` yalnız imzada yazılırsa çağıranın değişkeni değişir.
- `return` olmayan fonksiyon `null` döndürür; dönüş tipi sayısal dizgiyi zorlar, olmayanı reddeder.
- `func_num_args()` ve `...$x` yutulan fazlalığı görünür kılar.

## Sonraki Adım

Fazla argümanın nereye gittiği görüldü: yok sayıldı ya da bir dizide toplandı. İndeksli ve İlişkisel Diziler dersi o diziye bakıyor: iki dizi birleştirildiğinde, aynı anahtarı taşıyan elemanlar için anahtarlar nasıl birleşiyor?
