1-4 bo'lim mashqlari

~45 daq · PHP · Funksiyalar

Qanday ishlash kerak

Siz hozirgacha o'zgaruvchilar, turlar, stringlar, shartlar, sikllar, massivlar va funksiyalarni o'rgandingiz. Bu — PHP ning poydevori. Keyingi bo'limlarda (formalar, bazalar, OOP) hammasi shu poydevor ustiga quriladi.

Qoidalar:

  1. Har bir masalani avval o'zingiz yeching. Kamida 15 daqiqa urinib ko'ring.
  2. Har bir fayl declare(strict_types=1); bilan boshlansin.
  3. Funksiyalarga parametr va qaytish turlarini yozing.
  4. Natijani php fayl.php bilan tekshiring.
  5. Shundan keyingina yechimga qarang.

Yechimni ko'chirib olish — hech narsa o'rgatmaydi. Xato qilib, var_dump() bilan sababini topish — o'rgatadi.


1-masala: Harorat o'girgich ⭐

Selsiy darajasini Farengeytga o'giradigan funksiya yozing. Formula: F = C × 9/5 + 32.

echo selsiydanFarengeyt(0);     // 32
echo selsiydanFarengeyt(100);   // 212
echo selsiydanFarengeyt(36.6);  // 97.88
Yechim
<?php

declare(strict_types=1);

function selsiydanFarengeyt(float $c): float
{
    return round($c * 9 / 5 + 32, 2);
}

echo selsiydanFarengeyt(0) . PHP_EOL;
echo selsiydanFarengeyt(100) . PHP_EOL;
echo selsiydanFarengeyt(36.6) . PHP_EOL;

strict_types da ham int ni float parametrga berish mumkin — shuning uchun selsiydanFarengeyt(0) ishlaydi.


2-masala: Juft yoki toq ⭐

1 dan 20 gacha sonlarni chiqaring. Har birining yonida "juft" yoki "toq" deb yozilsin.

1 — toq
2 — juft
3 — toq
...
Yechim
<?php

declare(strict_types=1);

for ($i = 1; $i <= 20; $i++) {
    $turi = $i % 2 === 0 ? "juft" : "toq";
    echo "$i — $turi" . PHP_EOL;
}

3-masala: FizzBuzz ⭐⭐

Dasturchilar suhbatidagi klassik masala. 1 dan 30 gacha sonlarni chiqaring, lekin:

  • 3 ga bo'linsa — son o'rniga Fizz
  • 5 ga bo'linsa — Buzz
  • ham 3 ga, ham 5 ga bo'linsa — FizzBuzz
Yechim
<?php

declare(strict_types=1);

for ($i = 1; $i <= 30; $i++) {
    echo match (true) {
        $i % 15 === 0 => "FizzBuzz",
        $i % 3 === 0  => "Fizz",
        $i % 5 === 0  => "Buzz",
        default       => $i,
    } . PHP_EOL;
}

Eng ko'p uchraydigan xato — % 15 tekshiruvini oxiriga qo'yish. Unda 15 uchun Fizz chiqib qoladi, chunki birinchi mos kelgan shart ishlaydi (8-dars).


4-masala: Ism formatlash ⭐⭐

Foydalanuvchi kiritgan ism-familiyani tozalaydigan funksiya yozing: ortiqcha bo'sh joylar olib tashlansin, har bir so'z bosh harf bilan boshlansin.

echo ismniTozala("   aLIsher   naVOIY  ");   // Alisher Navoiy
echo ismniTozala("zahiriddin  muhammad bobur"); // Zahiriddin Muhammad Bobur

Maslahat: trim, strtolower, ucwords, explode, array_filter, implode.

Yechim
<?php

declare(strict_types=1);

function ismniTozala(string $ism): string
{
    $sozlar = explode(" ", strtolower(trim($ism)));
    $sozlar = array_filter($sozlar);          // so'zlar orasidagi bo'sh qismlarni olib tashlash
    return ucwords(implode(" ", $sozlar));
}

echo ismniTozala("   aLIsher   naVOIY  ") . PHP_EOL;
echo ismniTozala("zahiriddin  muhammad bobur") . PHP_EOL;

explode(" ", ...) ikki bo'sh joy orasida "" (bo'sh string) hosil qiladi. array_filter() funksiyasiz chaqirilsa ularni olib tashlaydi (13-dars).


5-masala: Savat hisobi ⭐⭐

Savatdagi mahsulotlar berilgan. Funksiya yozing:

  • Har bir mahsulot qatorini chiqarsin: nomi, soni × narxi = jami
  • Umumiy summani hisoblasin
  • Summa 500 000 dan oshsa — 10% chegirma qo'llasin
  • Narxlar 1 250 000 so'm formatida bo'lsin
$savat = [
    ["nom" => "Kitob",     "narx" => 85000,  "soni" => 3],
    ["nom" => "Quloqchin", "narx" => 249000, "soni" => 1],
    ["nom" => "Daftar",    "narx" => 12000,  "soni" => 5],
];

Kutilgan natija:

Kitob: 3 × 85 000 = 255 000 so'm
Quloqchin: 1 × 249 000 = 249 000 so'm
Daftar: 5 × 12 000 = 60 000 so'm
---
Jami: 564 000 so'm
Chegirma (10%): -56 400 so'm
To'lov: 507 600 so'm
Yechim
<?php

declare(strict_types=1);

function som(int|float $summa): string
{
    return number_format($summa, 0, '', ' ') . " so'm";
}

function savatHisobi(array $savat, int $chegirmaChegarasi = 500000, int $foiz = 10): void
{
    $jami = 0;

    foreach ($savat as $m) {
        $qator = $m['narx'] * $m['soni'];
        $jami += $qator;
        echo "{$m['nom']}: {$m['soni']} × " . number_format($m['narx'], 0, '', ' ') . " = " . som($qator) . PHP_EOL;
    }

    echo "---" . PHP_EOL;
    echo "Jami: " . som($jami) . PHP_EOL;

    $chegirma = $jami > $chegirmaChegarasi ? $jami * $foiz / 100 : 0;

    if ($chegirma > 0) {
        echo "Chegirma ($foiz%): -" . som($chegirma) . PHP_EOL;
    }

    echo "To'lov: " . som($jami - $chegirma) . PHP_EOL;
}

$savat = [
    ["nom" => "Kitob",     "narx" => 85000,  "soni" => 3],
    ["nom" => "Quloqchin", "narx" => 249000, "soni" => 1],
    ["nom" => "Daftar",    "narx" => 12000,  "soni" => 5],
];

savatHisobi($savat);

E'tibor bering: chegirma chegarasi va foizi — default qiymatli parametrlar. Ertaga aksiya bo'lsa, funksiyani o'zgartirmasdan savatHisobi($savat, foiz: 20) deb chaqirasiz.


6-masala: Talabalar reytingi ⭐⭐⭐

Talabalar va ularning ballari berilgan:

$talabalar = [
    ["ism" => "Aziza",  "ballar" => [85, 92, 78]],
    ["ism" => "Bobur",  "ballar" => [65, 70, 58]],
    ["ism" => "Dilnoza","ballar" => [95, 98, 100]],
    ["ism" => "Eldor",  "ballar" => [45, 52, 40]],
];

Quyidagilarni bajaring:

  1. Har bir talabaning o'rtacha balini hisoblang (1 xona aniqlikda)
  2. Baho qo'ying: 90+ → A'lo, 70+ → Yaxshi, 50+ → Qoniqarli, aks holda → Qoniqarsiz
  3. O'rtacha ball bo'yicha kamayish tartibida saralang
  4. Reyting jadvalini chiqaring
1. Dilnoza — 97.7 (A'lo)
2. Aziza — 85.0 (Yaxshi)
3. Bobur — 64.3 (Qoniqarli)
4. Eldor — 45.7 (Qoniqarsiz)

Maslahat: array_map, array_sum, count, round, usort, <=>, match (true), sprintf.

Yechim
<?php

declare(strict_types=1);

function baho(float $ball): string
{
    return match (true) {
        $ball >= 90 => "A'lo",
        $ball >= 70 => "Yaxshi",
        $ball >= 50 => "Qoniqarli",
        default     => "Qoniqarsiz",
    };
}

function ortacha(array $sonlar): float
{
    if (count($sonlar) === 0) {
        return 0.0;
    }
    return round(array_sum($sonlar) / count($sonlar), 1);
}

$talabalar = [
    ["ism" => "Aziza",   "ballar" => [85, 92, 78]],
    ["ism" => "Bobur",   "ballar" => [65, 70, 58]],
    ["ism" => "Dilnoza", "ballar" => [95, 98, 100]],
    ["ism" => "Eldor",   "ballar" => [45, 52, 40]],
];

// 1-2. O'rtacha va baho qo'shish
$natijalar = array_map(function (array $t): array {
    $ort = ortacha($t['ballar']);
    return [
        'ism'     => $t['ism'],
        'ortacha' => $ort,
        'baho'    => baho($ort),
    ];
}, $talabalar);

// 3. Kamayish tartibida saralash — $b va $a o'rni almashgan
usort($natijalar, fn($a, $b) => $b['ortacha'] <=> $a['ortacha']);

// 4. Chiqarish
foreach ($natijalar as $i => $n) {
    echo sprintf("%d. %s — %.1f (%s)", $i + 1, $n['ism'], $n['ortacha'], $n['baho']) . PHP_EOL;
}

Kamayish tartibi uchun $a <=> $b o'rniga $b <=> $a yoziladi — bu oddiy, lekin juda foydali hiyla.

ortacha() ichida bo'sh massiv tekshiruvi bor — busiz count() === 0 bo'lganda DivisionByZeroError chiqardi. Chegaraviy holatlarni doim o'ylang.


7-masala: Parol kuchliligi ⭐⭐⭐

Parolni tekshiruvchi funksiya yozing. U massiv qaytarsin: parol yaroqlimi va (agar yo'q bo'lsa) nima yetishmayotgani.

Talablar:

  • Kamida 8 belgi
  • Kamida bitta katta harf
  • Kamida bitta raqam
  • Bo'sh joy bo'lmasligi kerak
print_r(parolniTekshir("salom"));
// ['yaroqli' => false, 'xatolar' => ["Kamida 8 belgi bo'lsin", "Kamida bitta katta harf", "Kamida bitta raqam"]]

print_r(parolniTekshir("Toshkent2026"));
// ['yaroqli' => true, 'xatolar' => []]

Maslahat: strlen, str_contains, strtolower (katta harf borligini qanday aniqlash mumkin?), preg_match('/[0-9]/', $s) — raqam borligini tekshiradi.

Yechim
<?php

declare(strict_types=1);

/**
 * @return array{yaroqli: bool, xatolar: string[]}
 */
function parolniTekshir(string $parol): array
{
    $xatolar = [];

    if (strlen($parol) < 8) {
        $xatolar[] = "Kamida 8 belgi bo'lsin";
    }
    if (strtolower($parol) === $parol) {
        $xatolar[] = "Kamida bitta katta harf";   // kichik harfga o'tkazganda o'zgarmasa — katta harf yo'q
    }
    if (!preg_match('/[0-9]/', $parol)) {
        $xatolar[] = "Kamida bitta raqam";
    }
    if (str_contains($parol, ' ')) {
        $xatolar[] = "Bo'sh joy bo'lmasin";
    }

    return [
        'yaroqli' => count($xatolar) === 0,
        'xatolar' => $xatolar,
    ];
}

print_r(parolniTekshir("salom"));
print_r(parolniTekshir("Toshkent2026"));

Barcha xatolarni bir vaqtda yig'ib qaytarish — foydalanuvchi uchun qulay: u bitta urinishda nimani tuzatish kerakligini ko'radi. Haqiqiy saytda aynan shunday qilinadi.


O'zingizni tekshiring

Quyidagi savollarga javob bera olsangiz — keyingi bo'limga tayyorsiz:

  • == va === farqi nima? Qaysi birini ishlatish kerak va nima uchun?
  • 'Salom $ism' va "Salom $ism" qanday natija beradi?
  • match ning switch dan uchta afzalligini ayting.
  • foreach da & ishlatgandan keyin nima qilish shart?
  • sort() va array_map() natija qaytarishida qanday farq bor?
  • Funksiya ichida tashqi $x nima uchun ko'rinmaydi? Qanday to'g'ri yechiladi?
  • fn va function ning ikki asosiy farqi nima?

Keyingi bo'lim

5-bo'lim: PHP va Veb — HTML ichida PHP, formalar ($_GET, $_POST), ma'lumotni tekshirish, sessiya va cookie. Endi PHP ni brauzer bilan bog'laymiz.