6-bo‘lim
Shartlar va sikllar
if, match, switch, foreach va while - qaysi birini qachon tanlash va HTML bilan aralashtirishning toza usuli.
Ushbu bo‘lim mundarijasi
Har qanday dastur ikki narsadan iborat: qaror qabul qilish va takrorlash. Bu bo'limda ikkalasini ham zamonaviy PHP uslubida yozamiz.
if va qisqa shakllar #
// Har bir misol qat'iy turlar rejimida ishlaydi.
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";
95 -> a'lo
84 -> yaxshi
65 -> qoniqarli
42 -> qoniqarsiz
Ombor: tugagan
Toifa: kattalar
match - PHP 8 ning eng foydali qo'shimchasi #
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";
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 farqswitch | match | |
|---|---|---|
| Solishtirish | == (bo'sh) | === (qat'iy) |
break kerakmi | Ha, unutsangiz "oqib ketadi" | Yo'q |
| Qiymat qaytaradimi | Yo'q | Ha |
| Mos kelmasa | Jimgina o'tib ketadi | Xato tashlaydi |
Ikkinchi va to'rtinchi qatorlar eng muhimi.
break unutish - switch dagi klassik xato:
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 #
$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";
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'lingBu PHP dagi eng mashhur tuzoqlardan biri:
$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:
foreach ($sonlar as &$son) { ... }
unset($son); // 1. havolani uzing
$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.
break, continue va darajalar #
$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";
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:
<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>
HTML ichida figurali qavs ishlatilsa, yopuvchi }
belgilari ko'zdan yo'qoladi:
<?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:
| Ochilish | Yopilish |
|---|---|
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 #
$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, ",", " "));
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
if/elseifzanjiri bilan baho aniqlovchi funksiya yozing.- Uni
match (true)ga aylantiring - qaysi biri o'qishli? switchdabreakni ataylab unutib, natijani ko'ring.matchda mos kelmaydigan qiymat bering - qanday xato chiqadi?foreachda havola (&$x) ishlatib, keyin yana bir tsikl yozing.- Muammoni
unset()bilan tuzating. - Xuddi shu ishni
array_mapbilan havolasiz bajaring. continuebilan ba'zi elementlarni o'tkazib yuboring.- Ichma-ich tsiklda
break 2ni sinab ko'ring. - Shablon faylini muqobil sintaksis bilan yozing.
Xulosa #
if/elseifzanjiri uzayib ketsa - unimatch (true)ga aylantiring.matchqat'iy (===) solishtiradi, qiymat qaytaradi vabreaktalab qilmaydi.- Mos kelmagan holatda
matchxato tashlaydi -switchesa jimgina o'tib ketadi. matchfaqat ifoda: har bir shoxda bitta qiymat bo'ladi.- Massiv bo'ylab yurish uchun
foreach- holatlarning aksariyatida yetarli. foreachda havola (&$x) ishlatgandan keyinunset()ni unutmang.- Havola o'rniga
array_mapishlatish xavfsizroq. break 2ichma-ich tsikllardan birdan chiqaradi.- Shablon fayllarida muqobil sintaksis (
endforeach;) ishlating. - Shablonda chiqarilayotgan har bir qiymatga
htmlspecialcharsqo'llang.
Keyingi bo'limda funksiyalar - argumentlar, turlar, nomli argumentlar va yopilmalarni ko'ramiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
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.