İçeriğe geç
Educora
Başlangıç18 dk5 / 10

Fonksiyonlar, ok fonksiyonları ve kapanışlar

Tür belirtilmiş parametreleri ve dönüş türü olan fonksiyonlar yaz; varsayılan ve adlandırılmış argümanları, ok fonksiyonlarını ve kapanışları kullan; dizileri array_map, array_filter ve usort ile işle.

Kendini test et
Bu derste öğreneceklerin
  • Parametre ve dönüş türleri olan fonksiyonlar yazmak ve strict_types'ın rolünü açıklamak
  • Varsayılan, adlandırılmış ve değişken sayıda argüman kullanmak
  • array_map, array_filter, array_reduce ve usort'u ok fonksiyonları ve kapanışlarla uygulamak

Bir mağaza sitesinde bir ürünün KDV'li fiyatını on farklı yerde hesapladığını düşün. Vergi oranı değiştiğinde on yeri düzeltmen gerekir ve birini mutlaka unutursun. Fonksiyon bu sorunu çözer: kodu bir kez yazar, ona bir ad verir ve gereken her yerde çağırırsın.

Tür belirtilmiş fonksiyonlar

Bir fonksiyon function anahtar sözcüğüyle tanımlanır. Modern PHP'de parametre türlerini (float $price) ve dönüş türünü (: float) yazmak yerleşik bir alışkanlıktır. Hiçbir şey döndürmeyen fonksiyon : void, null da döndürebilen fonksiyon ?string, birkaç türden birini kabul eden parametre ise int|float şeklinde yazılır.

PHP
<?php

declare(strict_types=1);

function fullPrice(float $price, int $quantity = 1): float
{
    return $price * $quantity;
}

function greet(string $name): string
{
    return "Hello, $name!";
}

echo greet("Aysel"), "\n";
echo fullPrice(2.5, 4), "\n";
echo fullPrice(7.5), "\n";
Beklenen çıktı
Hello, Aysel!
10
7.5

Dosyanın ilk satırındaki declare(strict_types=1); katı modu açar. Bu modda PHP, "5" dizesinin bir int parametresine verilmesine izin vermez ve TypeError fırlatır. Katı mod olmadan PHP değeri dönüştürmeye çalışır ve hatalar gizli kalır. Tek istisna: bir int değeri her zaman bir float parametresine verilebilir.

Türsüz: hata gizlenir
function add($a, $b)
{
    return $a + $b;
}

echo add("5", "3"); // 8, works by accident
Türlü: hata hemen görünür
declare(strict_types=1);

function add(int $a, int $b): int
{
    return $a + $b;
}

echo add("5", "3"); // TypeError
Türler bir fonksiyonun “sözleşmesidir”: kod düzenleyicin de onları okur ve hataları sen daha yazarken gösterir.

Varsayılan, adlandırılmış ve değişken sayıda argümanlar

Bir parametrenin varsayılan değeri varsa çağrıda onu yazmayabilirsin. PHP 8'den beri adlandırılmış argümanlar vardır: bold: true yazarak aradaki parametreleri atlar ve gerekeni adıyla verirsin. ...$numbers istenen sayıda argümanı bir dizide toplar; çağrıda ise ...$marks bir diziyi ayrı argümanlara “açar”.

PHP
<?php

function makeTag(string $text, string $tag = "p", bool $bold = false): string
{
    $inner = $bold ? "<b>$text</b>" : $text;
    return "<$tag>$inner</$tag>";
}

function average(float ...$numbers): float
{
    return array_sum($numbers) / count($numbers);
}

echo makeTag("Hello"), "\n";
echo makeTag("Title", "h1"), "\n";
echo makeTag("Warning", bold: true), "\n";
echo average(4, 5, 3), "\n";
$marks = [5, 5, 4, 4];
echo average(...$marks), "\n";
Beklenen çıktı
<p>Hello</p>
<h1>Title</h1>
<p><b>Warning</b></p>
4
4.5

Anonim fonksiyonlar ve kapanışlar

PHP'de fonksiyon bir değerdir: adsız bir fonksiyonu bir değişkene yazıp sonra çağırabilirsin. Dışarıdaki bir değişkeni görmek için anonim fonksiyon onu use ($rate) ile “yakalar”; böyle bir fonksiyona kapanış (closure) denir. Ok fonksiyonu fn($x) => ... (PHP 7.4) daha kısadır: tek bir ifadeden oluşur ve dış değişkenleri otomatik olarak yakalar.

PHP
<?php

$rate = 1.7;

$toAzn = function (float $usd) use ($rate): float {
    return $usd * $rate;
};
$toUsd = fn(float $azn): float => round($azn / $rate, 2);

echo $toAzn(10), "\n";
echo $toUsd(34), "\n";

function makeCounter(): Closure
{
    $count = 0;
    return function () use (&$count): int {
        return ++$count;
    };
}

$next = makeCounter();
$next();
$next();
echo $next(), "\n";
Beklenen çıktı
17
20
3

use ($rate) değerin bir kopyasını yakalar. use (&$count) ise değişkenin kendisine başvurur; bu yüzden sayaç her çağrıda artar ve makeCounter bittikten sonra da yaşamaya devam eder. Ok fonksiyonları her zaman değer ile yakalar ve dışarıdaki bir değişkeni değiştiremez.

Dizi fonksiyonlarının içindeki fonksiyonlar

Kapanışlar en çok dizi fonksiyonlarıyla kullanılır. array_map her elemanı dönüştürür, array_filter koşulu sağlayan elemanları tutar, array_reduce diziyi tek bir değere “indirger”, usort ise senin karşılaştırma fonksiyonuna göre sıralar. Aşağıda fiyatlara %18 KDV ekliyor ve öğrencileri puana göre diziyoruz.

PHP
<?php

$prices = [12, 45, 7, 30];

$withVat = array_map(fn($p) => $p * 1.18, $prices);
echo implode(", ", $withVat), "\n";

$expensive = array_filter($prices, fn($p) => $p > 10);
print_r($expensive);

$total = array_reduce($prices, fn($sum, $p) => $sum + $p, 0);
echo $total, "\n";

$students = [
    ["name" => "Murad", "score" => 78],
    ["name" => "Leyla", "score" => 95],
    ["name" => "Elvin", "score" => 86],
];
usort($students, fn($a, $b) => $b["score"] <=> $a["score"]);
echo implode(", ", array_column($students, "name")), "\n";
Beklenen çıktı
14.16, 53.1, 8.26, 35.4
Array
(
    [0] => 12
    [1] => 45
    [3] => 30
)
94
Leyla, Elvin, Murad

Önemli noktalar

  • Parametre ve dönüş türlerini yaz; declare(strict_types=1) otomatik dönüşümleri yasaklar ve hataları ortaya çıkarır.
  • Varsayılan değerli parametreler atlanabilir; adlandırılmış argümanlar (bold: true) aradakileri geçmeyi sağlar.
  • ...$args argümanları bir dizide toplar; çağrıda ...$array ise diziyi argümanlara açar.
  • Kapanış dış değişkenleri use ile (& ile başvuru olarak) yakalar; ok fonksiyonu fn ise otomatik olarak ve değerle yakalar.
  • array_map, array_filter, array_reduce ve usort kapanışlarla dizileri kısa ve anlaşılır biçimde işler; array_filter anahtarları korur.

Kendini test et

10 soru. Her doğru cevap XP kazandırır.

1 / 10
Bir dosyada declare(strict_types=1); var. function add(int $a, int $b): int fonksiyonunu add("5", "3") şeklinde çağırırsak ne olur?