6-bo‘lim

Shartlar va sikllar

if, match, switch, foreach va while - qaysi birini qachon tanlash va HTML bilan aralashtirishning toza usuli.

🕑 11 daqiqa o‘qish 📄 554 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. if va qisqa shakllar
  2. match - PHP 8 ning eng foydali qo'shimchasi
  3. Sikllar
  4. break, continue va darajalar
  5. HTML bilan aralashtirish
  6. Amaliy misol: hisobot
  7. Xulosa

Har qanday dastur ikki narsadan iborat: qaror qabul qilish va takrorlash. Bu bo'limda ikkalasini ham zamonaviy PHP uslubida yozamiz.

if va qisqa shakllar #

PHP
// Har bir misol qat'iy turlar rejimida ishlaydi.
PHP
function bahoniAyt(int $ball): string
{
    if ($ball >= 90) {
        return "a'lo";
    } elseif ($ball >= 70) {
        return "yaxshi";
    } elseif ($ball >= 60) {
        return "qoniqarli";
    }
    return "qoniqarsiz";
}

foreach ([95, 84, 65, 42] as $ball) {
    printf("%3d -> %s\n", $ball, bahoniAyt($ball));
}

echo "\n";
// Uchlik operator - qisqa shart
$soni = 0;
echo "Ombor: " . ($soni > 0 ? "mavjud" : "tugagan") . "\n";

// Zanjir qilib yozmang - o'qib bo'lmaydi
$yosh = 25;
$toifa = $yosh < 18 ? "bola" : ($yosh < 60 ? "kattalar" : "keksa");
echo "Toifa: {$toifa}\n";
Natija
 95 -> a'lo
 84 -> yaxshi
 65 -> qoniqarli
 42 -> qoniqarsiz

Ombor: tugagan
Toifa: kattalar

match - PHP 8 ning eng foydali qo'shimchasi #

PHP
function javobMatni(int $kod): string
{
    return match (true) {
        $kod >= 200 && $kod < 300 => "muvaffaqiyat",
        $kod >= 300 && $kod < 400 => "yo'naltirish",
        $kod >= 400 && $kod < 500 => "mijoz xatosi",
        $kod >= 500               => "server xatosi",
        default                   => "noma'lum",
    };
}

function kodNomi(int $kod): string
{
    return match ($kod) {
        200      => "OK",
        301, 302 => "Ko'chirilgan",
        404      => "Topilmadi",
        500      => "Ichki xato",
        default  => "Boshqa",
    };
}

printf("%-6s %-16s %s\n", "KOD", "NOMI", "TOIFA");
echo str_repeat("-", 44) . "\n";
foreach ([200, 301, 404, 500, 418] as $kod) {
    printf("%-6d %-16s %s\n", $kod, kodNomi($kod), javobMatni($kod));
}

echo "\n";
// match QAYTARADI - shuning uchun uni to'g'ridan-to'g'ri tayinlash mumkin
$til = "uz";
$salom = match ($til) {
    "uz" => "Assalomu alaykum",
    "en" => "Hello",
    "ru" => "Zdravstvuyte",
};
echo "Salom: {$salom}\n";
Natija
KOD    NOMI             TOIFA
--------------------------------------------
200    OK               muvaffaqiyat
301    Ko'chirilgan     yo'naltirish
404    Topilmadi        mijoz xatosi
500    Ichki xato       server xatosi
418    Boshqa           mijoz xatosi

Salom: Assalomu alaykum
match va switch - to'rt muhim farq
switchmatch
Solishtirish== (bo'sh)=== (qat'iy)
break kerakmiHa, unutsangiz "oqib ketadi"Yo'q
Qiymat qaytaradimiYo'qHa
Mos kelmasaJimgina o'tib ketadiXato tashlaydi

Ikkinchi va to'rtinchi qatorlar eng muhimi.

break unutish - switch dagi klassik xato:

PHP
switch ($rol) {
    case "admin":
        $huquq = "hammasi";     // break YO'Q
    case "mehmon":
        $huquq = "o'qish";      // admin ham SHU YERGA tushadi
}

default yo'qligi ham xavfli. switch bunday holatda hech narsa qilmaydi va $huquq aniqlanmagan qoladi. match esa UnhandledMatchError tashlaydi - ya'ni siz muammoni darhol bilib olasiz.

match (true) shakli esa if/elseif zanjirini almashtiradi va uni ancha o'qishli qiladi - yuqoridagi javobMatni shunga misol.

Bitta cheklov: match faqat ifoda, blok emas. Har bir shoxda bitta qiymat bo'lishi kerak. Murakkab mantiq kerak bo'lsa - funksiyaga ajrating.

Sikllar #

PHP
$savat = [
    "Klaviatura" => 350000,
    "Sichqoncha" => 120000,
    "Monitor"    => 2400000,
];

echo "foreach - kalit va qiymat:\n";
foreach ($savat as $nom => $narx) {
    printf("  %-12s %s so'm\n", $nom, number_format($narx, 0, ",", " "));
}

echo "\nfor - aniq marta takrorlash:\n";
for ($i = 1; $i <= 3; $i++) {
    echo "  {$i}-urinish\n";
}

echo "\nwhile - shart rost ekan:\n";
$qoldiq = 100000;
$kun = 0;
while ($qoldiq > 0) {
    $qoldiq -= 30000;
    $kun++;
    if ($qoldiq < 0) {
        $qoldiq = 0;
    }
}
echo "  {$kun} kunda tugadi\n";

echo "\ndo-while - kamida bir marta bajariladi:\n";
$son = 10;
do {
    echo "  qiymat: {$son}\n";
    $son++;
} while ($son < 10);
echo "  (shart yolg'on bo'lsa ham bir marta ishladi)\n";
Natija
foreach - kalit va qiymat:
  Klaviatura   350 000 so'm
  Sichqoncha   120 000 so'm
  Monitor      2 400 000 so'm

for - aniq marta takrorlash:
  1-urinish
  2-urinish
  3-urinish

while - shart rost ekan:
  4 kunda tugadi

do-while - kamida bir marta bajariladi:
  qiymat: 10
  (shart yolg'on bo'lsa ham bir marta ishladi)
foreach da havola bilan ishlaganda ehtiyot bo'ling

Bu PHP dagi eng mashhur tuzoqlardan biri:

PHP
$sonlar = [1, 2, 3];
foreach ($sonlar as &$son) {
    $son *= 2;
}
// $son hali ham OXIRGI elementga HAVOLA
foreach ($sonlar as $son) {
    // har bir iteratsiya $sonlar[2] ni qayta yozadi
}
// Natija: [2, 4, 4]  - kutilgan [2, 4, 6] emas

Birinchi tsikl to'g'ri ishlaydi. Muammo shundaki, $son o'zgaruvchisi tsikldan keyin ham oxirgi elementga havola bo'lib qoladi. Ikkinchi tsikl unga qiymat tayinlaganda, aslida $sonlar[2] ni o'zgartiradi.

Ikki yechim bor:

PHP
foreach ($sonlar as &$son) { ... }
unset($son);                      // 1. havolani uzing
PHP
$sonlar = array_map(fn($s) => $s * 2, $sonlar);   // 2. havolasiz

Ikkinchisi afzal. array_map yangi massiv qaytaradi va hech qanday yashirin holat qoldirmaydi.

Havolani faqat juda katta massivlarni nusxalamasdan o'zgartirish kerak bo'lgandagina ishlating - va o'shanda ham unset() ni unutmang.

Qaysi vositani tanlash foreach Massiv yoki obyekt bo'ylab Indeks kerak emas Xatosi kam 90% holatda shu for Aniq marta takrorlash Indeks bilan ishlash Teskari yo'nalish Sanoq kerak bo'lsa while Necha marta - noma'lum Fayl o'qish, navbat Shart o'zgarishiga bog'liq Cheksiz tsikldan ehtiyot switch Bo'sh solishtirish, break majburiy, mos kelmasa jimgina o'tib ketadi. match Qat'iy solishtirish, qiymat qaytaradi, mos kelmasa XATO tashlaydi. Yangi kodda switch o'rniga match ni tanlang match (true) shakli uzun if/elseif zanjirini ham almashtiradi. Faqat blok kerak bo'lganda switch yoki if ga qayting.
Aksariyat holatda foreach va match yetarli

break, continue va darajalar #

PHP
$buyurtmalar = [
    ["id" => 1, "holat" => "yangi",     "summa" => 450000],
    ["id" => 2, "holat" => "bekor",     "summa" => 120000],
    ["id" => 3, "holat" => "yangi",     "summa" => 890000],
    ["id" => 4, "holat" => "yakunlangan", "summa" => 230000],
    ["id" => 5, "holat" => "yangi",     "summa" => 670000],
];

echo "continue - bekor qilinganlarni o'tkazib yuboramiz:\n";
$jami = 0;
foreach ($buyurtmalar as $b) {
    if ($b["holat"] === "bekor") {
        continue;
    }
    $jami += $b["summa"];
    printf("  #%d %-12s %s\n", $b["id"], $b["holat"],
           number_format($b["summa"], 0, ",", " "));
}
echo "  Jami: " . number_format($jami, 0, ",", " ") . " so'm\n";

echo "\nbreak - birinchi katta buyurtmani topamiz:\n";
foreach ($buyurtmalar as $b) {
    if ($b["summa"] > 500000) {
        echo "  Topildi: #{$b['id']} - " . number_format($b["summa"], 0, ",", " ") . "\n";
        break;
    }
}

echo "\nIchma-ich tsiklda break 2:\n";
$jadval = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
foreach ($jadval as $qator) {
    foreach ($qator as $katak) {
        if ($katak === 5) {
            echo "  5 topildi - IKKALA tsikldan chiqamiz\n";
            break 2;
        }
        echo "  ko'rildi: {$katak}\n";
    }
}
echo "  tsikldan keyin\n";
Natija
continue - bekor qilinganlarni o'tkazib yuboramiz:
  #1 yangi        450 000
  #3 yangi        890 000
  #4 yakunlangan  230 000
  #5 yangi        670 000
  Jami: 2 240 000 so'm

break - birinchi katta buyurtmani topamiz:
  Topildi: #3 - 890 000

Ichma-ich tsiklda break 2:
  ko'rildi: 1
  ko'rildi: 2
  ko'rildi: 3
  ko'rildi: 4
  5 topildi - IKKALA tsikldan chiqamiz
  tsikldan keyin

HTML bilan aralashtirish #

Shablon fayllarida figurali qavs o'rniga muqobil sintaksis ishlatiladi:

PHP
<ul class="mahsulotlar">
<?php foreach ($mahsulotlar as $m): ?>
    <li>
        <?= htmlspecialchars($m['nom']) ?>
        <?php if ($m['soni'] > 0): ?>
            <span class="bor">mavjud</span>
        <?php else: ?>
            <span class="yoq">tugagan</span>
        <?php endif; ?>
    </li>
<?php endforeach; ?>
</ul>
Muqobil sintaksis nima uchun yaxshiroq

HTML ichida figurali qavs ishlatilsa, yopuvchi } belgilari ko'zdan yo'qoladi:

PHP
<?php foreach ($m as $x) { ?>
    <li><?= $x ?>
<?php if ($x) { ?>
    ...
<?php } } ?>          ← qaysi biri qaysini yopyapti?

Muqobil sintaksisda esa har bir blok o'z nomi bilan yopiladi:

OchilishYopilish
if:endif;
foreach:endforeach;
for:endfor;
while:endwhile;
switch:endswitch;

Bu ayniqsa uzun shablonlarda qimmatli - 50 qator pastda endforeach; ni ko'rib, qaysi blok tugaganini darhol tushunasiz.

Qoida: mantiq faylida figurali qavs, shablon faylida muqobil sintaksis.

Va htmlspecialchars ni unutmang - u 17-bo'limdagi XSS himoyasining asosi.

Amaliy misol: hisobot #

PHP
$sotuvlar = [
    ["sana" => "2024-09-01", "mahsulot" => "Klaviatura", "soni" => 3,  "narx" => 350000],
    ["sana" => "2024-09-01", "mahsulot" => "Sichqoncha", "soni" => 5,  "narx" => 120000],
    ["sana" => "2024-09-02", "mahsulot" => "Monitor",    "soni" => 1,  "narx" => 2400000],
    ["sana" => "2024-09-02", "mahsulot" => "Klaviatura", "soni" => 2,  "narx" => 350000],
    ["sana" => "2024-09-03", "mahsulot" => "Quloqchin",  "soni" => 12, "narx" => 89000],
];

// Sana bo'yicha guruhlash
$kunlik = [];
foreach ($sotuvlar as $s) {
    $summa = $s["soni"] * $s["narx"];
    $kunlik[$s["sana"]] ??= ["summa" => 0, "soni" => 0];
    $kunlik[$s["sana"]]["summa"] += $summa;
    $kunlik[$s["sana"]]["soni"]  += $s["soni"];
}

ksort($kunlik);

printf("%-12s %8s %16s %s\n", "SANA", "DONA", "SUMMA", "DARAJA");
echo str_repeat("-", 56) . "\n";

$engKatta = max(array_column($kunlik, "summa"));

foreach ($kunlik as $sana => $k) {
    $ulush = (int) round($k["summa"] / $engKatta * 20);
    printf(
        "%-12s %8d %16s %s\n",
        $sana,
        $k["soni"],
        number_format($k["summa"], 0, ",", " "),
        str_repeat("#", $ulush)
    );
}

echo str_repeat("-", 56) . "\n";
$umumiy = array_sum(array_column($kunlik, "summa"));
printf("%-12s %8d %16s\n", "JAMI",
       array_sum(array_column($kunlik, "soni")),
       number_format($umumiy, 0, ",", " "));
Natija
SANA             DONA            SUMMA DARAJA
--------------------------------------------------------
2024-09-01          8        1 650 000 ###########
2024-09-02          3        3 100 000 ####################
2024-09-03         12        1 068 000 #######
--------------------------------------------------------
JAMI               23        5 818 000
Amaliy topshiriq
  1. if/elseif zanjiri bilan baho aniqlovchi funksiya yozing.
  2. Uni match (true) ga aylantiring - qaysi biri o'qishli?
  3. switch da break ni ataylab unutib, natijani ko'ring.
  4. match da mos kelmaydigan qiymat bering - qanday xato chiqadi?
  5. foreach da havola (&$x) ishlatib, keyin yana bir tsikl yozing.
  6. Muammoni unset() bilan tuzating.
  7. Xuddi shu ishni array_map bilan havolasiz bajaring.
  8. continue bilan ba'zi elementlarni o'tkazib yuboring.
  9. Ichma-ich tsiklda break 2 ni sinab ko'ring.
  10. Shablon faylini muqobil sintaksis bilan yozing.

Xulosa #

  • if/elseif zanjiri uzayib ketsa - uni match (true) ga aylantiring.
  • match qat'iy (===) solishtiradi, qiymat qaytaradi va break talab qilmaydi.
  • Mos kelmagan holatda match xato tashlaydi - switch esa jimgina o'tib ketadi.
  • match faqat ifoda: har bir shoxda bitta qiymat bo'ladi.
  • Massiv bo'ylab yurish uchun foreach - holatlarning aksariyatida yetarli.
  • foreach da havola (&$x) ishlatgandan keyin unset() ni unutmang.
  • Havola o'rniga array_map ishlatish xavfsizroq.
  • break 2 ichma-ich tsikllardan birdan chiqaradi.
  • Shablon fayllarida muqobil sintaksis (endforeach;) ishlating.
  • Shablonda chiqarilayotgan har bir qiymatga htmlspecialchars qo'llang.

Keyingi bo'limda funksiyalar - argumentlar, turlar, nomli argumentlar va yopilmalarni ko'ramiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.