Məzmuna keç
Educora
Başlanğıc18 dəq5 / 10

Funksiyalar, ox funksiyaları və qapanmalar

Tipli parametrləri və qaytarılan tipi olan funksiyalar yaz, defolt və adlı arqumentlərdən, ox funksiyalarından və qapanmalardan istifadə et, massivləri array_map, array_filter və usort ilə emal et.

Özünü yoxla
Bu dərsdə öyrənəcəksən
  • Parametr və qaytarılan qiymət tipləri olan funksiyalar yazmaq, strict_types-ın rolunu izah etmək
  • Defolt, adlı və dəyişən sayda arqumentlərdən istifadə etmək
  • Ox funksiyaları və qapanmalarla array_map, array_filter, array_reduce və usort-u tətbiq etmək

Təsəvvür et ki, mağaza saytında məhsulun ƏDV-li qiymətini on müxtəlif yerdə hesablayırsan. Vergi dərəcəsi dəyişəndə on yeri düzəltməli olacaqsan və biri mütləq yaddan çıxacaq. Funksiya bu problemi həll edir: kodu bir dəfə yazırsan, ona ad verirsən və istənilən yerdə çağırırsan.

Tipli funksiyalar

Funksiya function açar sözü ilə elan olunur. Müasir PHP-də parametrlərin tipini (float $price) və qaytarılan qiymətin tipini (: float) yazmaq qəbul olunub. Heç nə qaytarmayan funksiya : void, null da qaytara bilən funksiya ?string, bir neçə tipdən birini qəbul edən parametr isə int|float kimi 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";
Gözlənilən nəticə
Hello, Aysel!
10
7.5

Faylın ilk sətrindəki declare(strict_types=1); sərt rejimi aktivləşdirir. Bu rejimdə PHP "5" sətrini int parametrinə ötürməyə icazə vermir və TypeError atır. Sərt rejim olmadan PHP qiyməti çevirməyə çalışır və səhvlər gizli qalır. Yeganə istisna: int qiyməti float parametrinə həmişə ötürmək olar.

Tipsiz: səhv gizlənir
function add($a, $b)
{
    return $a + $b;
}

echo add("5", "3"); // 8, works by accident
Tipli: səhv dərhal görünür
declare(strict_types=1);

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

echo add("5", "3"); // TypeError
Tiplər funksiyanın «müqaviləsidir»: redaktor də onları oxuyur və səhvləri hələ kod yazılarkən göstərir.

Defolt, adlı və dəyişən sayda arqumentlər

Parametrə defolt qiymət versən, onu çağırışda buraxmaq olar. PHP 8-dən adlı arqumentlər var: bold: true yazaraq aradakı parametrləri keçib lazım olanı adı ilə ötürürsən. ...$numbers isə istənilən sayda arqumenti bir massivdə toplayır, çağırışda ...$marks massivi ayrı arqumentlərə «açır».

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";
Gözlənilən nəticə
<p>Hello</p>
<h1>Title</h1>
<p><b>Warning</b></p>
4
4.5

Anonim funksiyalar və qapanmalar

PHP-də funksiya qiymətdir: adsız funksiyanı dəyişənə yazıb sonra çağırmaq olar. Xarici dəyişəni görmək üçün anonim funksiya onu use ($rate) ilə «tutur» — belə funksiyaya qapanma (closure) deyilir. Ox funksiyası fn($x) => ... (PHP 7.4) daha qısadır: yalnız bir ifadədən ibarətdir və xarici dəyişənləri avtomatik tutur.

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";
Gözlənilən nəticə
17
20
3

use ($rate) qiymətin surətini tutur. use (&$count) isə dəyişənin özünə istinad edir, ona görə sayğac hər çağırışda artır və makeCounter bitdikdən sonra da yaşayır. Ox funksiyaları dəyişənləri həmişə qiymətlə tutur və xaricdəki dəyişəni dəyişə bilmir.

Funksiyalar massiv funksiyalarının içində

Qapanmaların ən çox işlədildiyi yer massiv funksiyalarıdır. array_map hər elementi çevirir, array_filter şərtə uyğun elementləri saxlayır, array_reduce massivi bir qiymətə «yığır», usort isə sənin müqayisə funksiyana görə sıralayır. Aşağıda qiymətlərə 18 % ƏDV əlavə edirik və şagirdləri bala görə düzürük.

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";
Gözlənilən nəticə
14.16, 53.1, 8.26, 35.4
Array
(
    [0] => 12
    [1] => 45
    [3] => 30
)
94
Leyla, Elvin, Murad

Əsas fikirlər

  • Parametr və qaytarılan tipləri yaz; declare(strict_types=1) avtomatik çevirmələri qadağan edir və səhvləri üzə çıxarır.
  • Defolt qiymətli parametrlər buraxıla bilər, adlı arqumentlər (bold: true) isə aradakıları keçməyə imkan verir.
  • ...$args arqumentləri massivə toplayır, çağırışda ...$array isə massivi arqumentlərə açır.
  • Qapanma xarici dəyişəni use ilə tutur (& ilə istinadla), ox funksiyası fn isə avtomatik və qiymətlə tutur.
  • array_map, array_filter, array_reduce və usort qapanmalarla massivləri qısa və aydın emal edir; array_filter açarları saxlayır.

Özünü yoxla

10 sual. Hər düzgün cavab XP qazandırır.

1 / 10
Faylda declare(strict_types=1); var. function add(int $a, int $b): int funksiyasını add("5", "3") kimi çağırsaq, nə olar?