foreach — massiv ustida yurish, kalit => qiymat

~12 daq · PHP · Massivlar

Muammodan boshlaylik

Massivni for bilan aylanib chiqish mumkin:

<?php

$ranglar = ["qizil", "yashil", "ko'k"];

for ($i = 0; $i < count($ranglar); $i++) {
    echo $ranglar[$i];
}

Lekin assotsiativ massivda $i umuman yo'q — kalitlar "ism", "email". Indeksli massivdan bitta element o'chirilsa (unset($ranglar[1])) — indekslar 0, 2 bo'lib qoladi va for xato beradi.

PHP da massiv ustida yurishning to'g'ri usuli — foreach.


Faqat qiymatlar

<?php

$ranglar = ["qizil", "yashil", "ko'k"];

foreach ($ranglar as $rang) {
    echo $rang . "\n";
}
qizil
yashil
ko'k

O'qilishi: "har bir $ranglar elementi uchun, uni $rang deb atab, quyidagini bajar".

Hisoblagich yo'q, count() yo'q, chegaradan chiqish xavfi yo'q.


Kalit va qiymat

<?php

$foydalanuvchi = [
    "ism"   => "Gulnora",
    "email" => "gulnora@mail.uz",
    "shahar" => "Buxoro",
];

foreach ($foydalanuvchi as $kalit => $qiymat) {
    echo "$kalit: $qiymat\n";
}
ism: Gulnora
email: gulnora@mail.uz
shahar: Buxoro

Indeksli massivda kalit — indeks raqami:

<?php

$gollar = ["Ronaldo", "Messi", "Mbappe"];

foreach ($gollar as $o_rin => $ism) {
    echo ($o_rin + 1) . ". $ism\n";
}
// 1. Ronaldo
// 2. Messi
// 3. Mbappe

Ko'p o'lchovli massiv — eng ko'p uchraydigan holat

Bazadan kelgan mahsulotlar ro'yxatini jadval qilib chiqarish:

<?php

$mahsulotlar = [
    ["nom" => "Telefon",   "narx" => 3200000, "soni" => 5],
    ["nom" => "Noutbuk",   "narx" => 8900000, "soni" => 0],
    ["nom" => "Quloqchin", "narx" => 249000,  "soni" => 12],
];

$jami = 0;

foreach ($mahsulotlar as $mahsulot) {
    $holat = $mahsulot["soni"] > 0 ? "Bor" : "Tugagan";
    echo "{$mahsulot['nom']} — " . number_format($mahsulot['narx'], 0, '', ' ') . " so'm ($holat)\n";
    $jami += $mahsulot["narx"] * $mahsulot["soni"];
}

echo "Ombordagi jami qiymat: " . number_format($jami, 0, '', ' ') . " so'm";
Telefon — 3 200 000 so'm (Bor)
Noutbuk — 8 900 000 so'm (Tugagan)
Quloqchin — 249 000 so'm (Bor)
Ombordagi jami qiymat: 18 988 000 so'm

HTML ichida foreach

Haqiqiy saytda aynan shunday ko'rinadi:

<table>
    <tr>
        <th>Nomi</th>
        <th>Narxi</th>
    </tr>
    <?php foreach ($mahsulotlar as $m): ?>
        <tr>
            <td><?= htmlspecialchars($m['nom']) ?></td>
            <td><?= number_format($m['narx'], 0, '', ' ') ?> so'm</td>
        </tr>
    <?php endforeach; ?>
</table>

htmlspecialchars() — matnni HTML ga xavfsiz chiqarish uchun. Nima uchun kerakligini 20-darsda batafsil ko'ramiz. Hozircha qoida: foydalanuvchi yoki bazadan kelgan matnni HTML ga chiqarishda doim htmlspecialchars().


Siklda massivni o'zgartirish: &

Odatiy foreach elementning nusxasi bilan ishlaydi:

<?php

$narxlar = [100, 200, 300];

foreach ($narxlar as $narx) {
    $narx = $narx * 2;   // faqat nusxa o'zgaradi
}

print_r($narxlar);   // [100, 200, 300] — o'zgarmadi!

Asl massivni o'zgartirish uchun — & (havola):

<?php

$narxlar = [100, 200, 300];

foreach ($narxlar as &$narx) {
    $narx = $narx * 2;
}
unset($narx);   // ← muhim!

print_r($narxlar);   // [200, 400, 600]

[!WARNING] & bilan foreach dan keyin har doim unset($narx) yozing. Aks holda $narx massivning oxirgi elementiga bog'langan holda qoladi va keyingi foreach ($narxlar as $narx) oxirgi elementni buzib yuboradi. Bu PHP dagi eng mashhur yashirin xatolardan biri.

Xavfsizroq alternativ — kalit orqali o'zgartirish:

<?php

foreach ($narxlar as $i => $narx) {
    $narxlar[$i] = $narx * 2;
}

Yoki array_map() — keyingi darsda.


break va continue

for dagi kabi ishlaydi:

<?php

$buyurtmalar = [
    ["id" => 101, "holat" => "paid"],
    ["id" => 102, "holat" => "cancelled"],
    ["id" => 103, "holat" => "paid"],
];

foreach ($buyurtmalar as $b) {
    if ($b["holat"] === "cancelled") {
        continue;   // bekor qilinganlarni o'tkazib yuborish
    }
    echo "Buyurtma #{$b['id']} yuborilsin\n";
}
// Buyurtma #101 yuborilsin
// Buyurtma #103 yuborilsin

Bo'sh massiv

<?php

$izohlar = [];

foreach ($izohlar as $izoh) {
    echo $izoh;   // hech qachon bajarilmaydi — xato ham yo'q
}

if (empty($izohlar)) {
    echo "Hali izohlar yo'q";
}

foreach bo'sh massivda jimgina hech narsa qilmaydi. Lekin foydalanuvchiga "hech narsa yo'q" deb ko'rsatish odatda kerak — empty() bilan tekshiring.


Nima uchun shunday?

Nima uchun foreach default holatda nusxa bilan ishlaydi?

Xavfsizlik uchun. Agar sikl doim asl massivni o'zgartirsa — tasodifiy o'zgarishlar kodning boshqa joylarida kutilmagan xatolarga olib keladi. "O'qish — xavfsiz, yozish — ataylab" tamoyili: o'zgartirmoqchi bo'lsangiz, & bilan buni ochiq ko'rsatasiz.


Tez-tez uchraydigan xatolar

Massiv emas narsani aylantirish:

<?php

$natija = null;   // masalan, bazadan hech narsa kelmadi
foreach ($natija as $x) { }
// Warning: foreach() argument must be of type array|object, null given

Yechim: foreach ($natija ?? [] as $x).

as tartibini adashtirish:

<?php

foreach ($ism as $ismlar) { }   // ❌ teskari
foreach ($ismlar as $ism) { }   // ✅ ko'plik → birlik

Nomlash odati: massiv — ko'plikda ($mahsulotlar), element — birlikda ($mahsulot).


Xulosa

Eslab qoling:

  • foreach ($massiv as $qiymat) — faqat qiymatlar
  • foreach ($massiv as $kalit => $qiymat) — kalit bilan
  • HTML da: foreach (...): ... endforeach;
  • Default — nusxa; asl massivni o'zgartirish uchun & va keyin unset()
  • Bo'sh massiv xato bermaydi; null esa beradi — ?? [] ishlating

Keyingi dars

13-dars: Massiv funksiyalari — count, in_array, sort, array_map, array_filter