Vòng lặp trong PHP

Sau khi nắm vững câu lệnh điều kiện trong PHP, bước tiếp theo là học cách thực thi code lặp đi lặp lại với vòng lặp trong PHP. Thay vì viết cùng một đoạn code 100 lần, bạn chỉ cần dùng vòng lặp để máy tính tự động làm việc đó. Từ in dãy số, duyệt mảng, tạo bảng cửu chương đến xử lý dữ liệu database – tất cả đều cần vòng lặp.

1. Vòng lặp là gì?

Vòng lặp (Loop) là cấu trúc giúp thực thi một đoạn code nhiều lần cho đến khi điều kiện dừng được thỏa mãn. Ví dụ thực tế:

  • ✅ In số từ 1 đến 100
  • ✅ Hiển thị danh sách 50 sản phẩm từ database
  • ✅ Tính tổng điểm của 30 sinh viên
  • ✅ Gửi email cho 1000 khách hàng
  • ✅ Tạo bảng cửu chương từ 1 đến 10

PHP cung cấp 4 loại vòng lặp chính:

  • for – Biết trước số lần lặp
  • while – Lặp khi điều kiện còn đúng
  • do...while – Lặp ít nhất 1 lần, sau đó kiểm tra điều kiện
  • foreach – Duyệt qua từng phần tử của mảng

CẤU TRÚC VÒNG LẶP FOR for ($i = 1; $i <= 5; $i++) { ... } 1. KHỞI TẠO $i = 1 Chạy 1 lần duy nhất 2. ĐIỀU KIỆN $i <= 5 Kiểm tra mỗi lần lặp 3. BƯỚC NHẢY $i++ Sau mỗi lần lặp QUÁ TRÌNH THỰC THI Lần 1: $i = 1 → Kiểm tra 1 <= 5 (✅) → Thực thi code → $i++ → $i = 2 Lần 2: $i = 2 → Kiểm tra 2 <= 5 (✅) → Thực thi code → $i++ → $i = 3 Lần 3: $i = 3 → Kiểm tra 3 <= 5 (✅) → Thực thi code → $i++ → $i = 4 Lần 4: $i = 4 → Kiểm tra 4 <= 5 (✅) → Thực thi code → $i++ → $i = 5 Lần 5: $i = 5 → Kiểm tra 5 <= 5 (✅) → Thực thi code → $i++ → $i = 6 Lần 6: $i = 6 → Kiểm tra 6 <= 5 (❌) → DỪNG VÒNG LẶP 💡 Vòng lặp chạy 5 lần, in ra: 1 2 3 4 5
Hình 1: Cấu trúc vòng lặp for trong PHP

2. Vòng lặp for

Dùng khi biết trước số lần lặp. Cú pháp gồm 3 phần: khởi tạo, điều kiện, bước nhảy.

<?php
// Cú pháp
for (khởi_tạo; điều_kiện; bước_nhảy) {
  // Code thực thi mỗi lần lặp
}

// Ví dụ 1: In số từ 1 đến 10
for ($i = 1; $i <= 10; $i++) {
  echo $i . " ";
}
// Kết quả: 1 2 3 4 5 6 7 8 9 10

// Ví dụ 2: In số chẵn từ 2 đến 20
for ($i = 2; $i <= 20; $i += 2) {
  echo $i . " ";
}
// Kết quả: 2 4 6 8 10 12 14 16 18 20

// Ví dụ 3: Đếm ngược từ 10 về 1
for ($i = 10; $i >= 1; $i--) {
  echo $i . " ";
}
// Kết quả: 10 9 8 7 6 5 4 3 2 1
?>

2.1. Phân tích cấu trúc vòng for

<?php
for ($i = 1; $i <= 5; $i++) {
  echo "Lần lặp thứ $i<br>";
}

/*
Giải thích:
- $i = 1         → Khởi tạo biến đếm từ 1
- $i <= 5        → Điều kiện: Lặp khi $i nhỏ hơn hoặc bằng 5
- $i++           → Sau mỗi lần lặp, tăng $i lên 1

Quá trình:
Lần 1: $i = 1 → Kiểm tra 1 <= 5 (true) → In "Lần lặp thứ 1" → $i++ → $i = 2
Lần 2: $i = 2 → Kiểm tra 2 <= 5 (true) → In "Lần lặp thứ 2" → $i++ → $i = 3
...
Lần 5: $i = 5 → Kiểm tra 5 <= 5 (true) → In "Lần lặp thứ 5" → $i++ → $i = 6
Lần 6: $i = 6 → Kiểm tra 6 <= 5 (false) → DỪNG
*/
?>

2.2. Ví dụ thực tế: Bảng cửu chương

<?php
$so = 7; // Bảng cửu chương 7

echo "<h3>Bảng cửu chương $so</h3>";

for ($i = 1; $i <= 10; $i++) {
  $ket_qua = $so * $i;
  echo "$so x $i = $ket_qua<br>";
}

/*
Kết quả:
7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
...
7 x 10 = 70
*/
?>

2.3. Vòng for lồng nhau (Nested For)

<?php
// In bảng cửu chương từ 2 đến 9
for ($bang = 2; $bang <= 9; $bang++) {
  echo "<h4>Bảng $bang</h4>";
  
  for ($i = 1; $i <= 10; $i++) {
    echo "$bang x $i = " . ($bang * $i) . "<br>";
  }
  
  echo "<br>";
}
?>

2.4. Tạo bảng HTML bằng vòng for

<?php
echo "<table border='1' cellpadding='5'>";
echo "<tr><th>STT</th><th>Họ tên</th><th>Điểm</th></tr>";

for ($i = 1; $i <= 5; $i++) {
  echo "<tr>";
  echo "<td>$i</td>";
  echo "<td>Sinh viên $i</td>";
  echo "<td>" . rand(5, 10) . "</td>";
  echo "</tr>";
}

echo "</table>";
?>

3. Vòng lặp while

Lặp khi điều kiện còn đúng. Dùng khi không biết trước số lần lặp.

<?php
// Cú pháp
while (điều_kiện) {
  // Code thực thi
  // Phải có câu lệnh thay đổi điều kiện để tránh vòng lặp vô tận
}

// Ví dụ 1: In số từ 1 đến 5
$i = 1;
while ($i <= 5) {
  echo $i . " ";
  $i++; // Quan trọng: Tăng $i để thoát vòng lặp
}
// Kết quả: 1 2 3 4 5

// Ví dụ 2: Tính tổng từ 1 đến 10
$i = 1;
$tong = 0;

while ($i <= 10) {
  $tong += $i;
  $i++;
}

echo "Tổng: $tong"; // Kết quả: 55
?>

3.1. Ví dụ thực tế: Đọc file từng dòng

<?php
$file = fopen("dulieu.txt", "r");

if ($file) {
  $dong_so = 1;
  
  while (!feof($file)) { // Lặp đến khi hết file
    $noi_dung = fgets($file);
    echo "Dòng $dong_so: $noi_dung<br>";
    $dong_so++;
  }
  
  fclose($file);
} else {
  echo "Không mở được file";
}
?>

3.2. So sánh for vs while

<?php
// Cùng kết quả, khác cách viết

// Dùng for
for ($i = 1; $i <= 5; $i++) {
  echo $i . " ";
}

// Dùng while
$i = 1;
while ($i <= 5) {
  echo $i . " ";
  $i++;
}

// Kết quả giống nhau: 1 2 3 4 5
?>

💡 Khi nào dùng for, khi nào dùng while?
- Dùng for khi biết trước số lần lặp (vd: lặp 10 lần, duyệt mảng có độ dài cố định)
- Dùng while khi điều kiện dừng phụ thuộc vào logic (vd: đọc file đến hết, nhập đến khi đúng)

4. Vòng lặp do...while

Giống while nhưng luôn thực thi ít nhất 1 lần vì kiểm tra điều kiện ở cuối.

<?php
// Cú pháp
do {
  // Code thực thi (chạy ít nhất 1 lần)
} while (điều_kiện);

// Ví dụ 1: In số từ 1 đến 5
$i = 1;
do {
  echo $i . " ";
  $i++;
} while ($i <= 5);
// Kết quả: 1 2 3 4 5

// Ví dụ 2: Điều kiện sai ngay từ đầu
$x = 10;

// while: Không chạy lần nào
while ($x < 5) {
  echo "While: $x ";
  $x++;
}

// do-while: Chạy 1 lần rồi mới kiểm tra
do {
  echo "Do-While: $x ";
  $x++;
} while ($x < 5);

// Kết quả: Do-While: 10
?>

4.1. Ví dụ thực tế: Menu nhập liệu

<?php
// Giả lập menu (thực tế dùng form HTML)
$lua_chon = 0;

do {
  echo "\n=== MENU ===\n";
  echo "1. Thêm sản phẩm\n";
  echo "2. Xem danh sách\n";
  echo "3. Thoát\n";
  echo "Nhập lựa chọn: ";
  
  $lua_chon = 2; // Giả lập nhập từ bàn phím
  
  switch ($lua_chon) {
    case 1:
      echo "Đã thêm sản phẩm\n";
      break;
    case 2:
      echo "Hiển thị danh sách\n";
      break;
    case 3:
      echo "Thoát chương trình\n";
      break;
    default:
      echo "Lựa chọn không hợp lệ\n";
  }
  
  $lua_chon = 3; // Giả lập thoát
  
} while ($lua_chon != 3);
?>

SO SÁNH CÁC LOẠI VÒNG LẶP FOR for ($i = 1; $i <= 5; $i++) { echo $i; } ✅ Khi nào: Biết trước số lần lặp 📌 Ưu: Gọn gàng, logic rõ ràng VD: Lặp 10 lần, duyệt mảng WHILE $i = 1; while ($i <= 5) { echo $i; $i++; ✅ Khi nào: Phụ thuộc điều kiện 📌 Ưu: Linh hoạt VD: Đọc file đến hết DO-WHILE $i = 1; do { echo $i; $i++; } while ($i <= 5); ✅ Khi nào: Chạy ít nhất 1 lần 📌 Ưu: Đảm bảo thực thi 1 lần VD: Menu nhập liệu FOREACH $arr = [1, 2, 3, 4, 5]; foreach ($arr as $val) { echo $val; } ✅ Khi nào: Duyệt mảng 📌 Ưu: Ngắn gọn, không lo index VD: Hiển thị danh sách
Hình 2: So sánh các loại vòng lặp

5. Vòng lặp foreach

Chuyên dùng để duyệt qua từng phần tử của mảng. Đơn giản và dễ đọc nhất.

<?php
// Cú pháp 1: Mảng indexed
foreach ($mang as $gia_tri) {
  // Code xử lý $gia_tri
}

// Cú pháp 2: Mảng associative
foreach ($mang as $key => $gia_tri) {
  // Code xử lý $key và $gia_tri
}

// Ví dụ 1: Duyệt mảng indexed
$mon_hoc = ["PHP", "JavaScript", "MySQL", "HTML", "CSS"];

foreach ($mon_hoc as $mon) {
  echo "- $mon<br>";
}

/*
Kết quả:
- PHP
- JavaScript
- MySQL
- HTML
- CSS
*/
?>

5.1. Foreach với mảng associative

<?php
$sinh_vien = [
  "ten" => "Nguyễn Văn A",
  "tuoi" => 20,
  "lop" => "CNTT K15",
  "diem" => 8.5
];

foreach ($sinh_vien as $key => $value) {
  echo "$key: $value<br>";
}

/*
Kết quả:
ten: Nguyễn Văn A
tuoi: 20
lop: CNTT K15
diem: 8.5
*/
?>

5.2. Foreach với mảng đa chiều

<?php
$danh_sach_sv = [
  ["ten" => "Trần Thị B", "diem" => 9.0],
  ["ten" => "Lê Văn C", "diem" => 7.5],
  ["ten" => "Phạm Thị D", "diem" => 8.0]
];

foreach ($danh_sach_sv as $sv) {
  echo "Tên: " . $sv['ten'] . " - Điểm: " . $sv['diem'] . "<br>";
}

/*
Kết quả:
Tên: Trần Thị B - Điểm: 9.0
Tên: Lê Văn C - Điểm: 7.5
Tên: Phạm Thị D - Điểm: 8.0
*/
?>

5.3. Ví dụ thực tế: Tạo dropdown HTML

<?php
$quoc_gia = [
  "VN" => "Việt Nam",
  "US" => "Hoa Kỳ",
  "JP" => "Nhật Bản",
  "KR" => "Hàn Quốc",
  "TH" => "Thái Lan"
];

echo "<select name='country'>";
echo "<option value=''>-- Chọn quốc gia --</option>";

foreach ($quoc_gia as $ma => $ten) {
  echo "<option value='$ma'>$ten</option>";
}

echo "</select>";
?>

5.4. Sửa đổi mảng trong foreach

<?php
// Dùng tham chiếu (&) để sửa giá trị gốc
$diem = [7.5, 8.0, 6.5, 9.0];

echo "Trước khi cộng điểm: ";
print_r($diem);

// Cộng thêm 0.5 điểm cho mỗi sinh viên
foreach ($diem as &$d) {
  $d += 0.5;
}

echo "<br>Sau khi cộng điểm: ";
print_r($diem);

// Kết quả: Array ( [0] => 8 [1] => 8.5 [2] => 7 [3] => 9.5 )
?>

6. Break và Continue

Điều khiển luồng vòng lặp:

6.1. Break - Thoát khỏi vòng lặp

<?php
// Tìm số chia hết cho 7 đầu tiên trong khoảng 50-100
for ($i = 50; $i <= 100; $i++) {
  if ($i % 7 == 0) {
    echo "Số đầu tiên chia hết cho 7: $i";
    break; // Dừng vòng lặp ngay
  }
}
// Kết quả: Số đầu tiên chia hết cho 7: 56

// Ví dụ 2: Tìm kiếm trong mảng
$san_pham = ["Laptop", "Chuột", "Bàn phím", "Màn hình"];
$tim_kiem = "Bàn phím";
$tim_thay = false;

foreach ($san_pham as $index => $sp) {
  if ($sp == $tim_kiem) {
    echo "Tìm thấy '$tim_kiem' ở vị trí $index";
    $tim_thay = true;
    break; // Không cần duyệt tiếp
  }
}

if (!$tim_thay) {
  echo "Không tìm thấy '$tim_kiem'";
}
?>

6.2. Continue - Bỏ qua lần lặp hiện tại

<?php
// In số lẻ từ 1 đến 10
for ($i = 1; $i <= 10; $i++) {
  if ($i % 2 == 0) {
    continue; // Bỏ qua số chẵn
  }
  echo $i . " ";
}
// Kết quả: 1 3 5 7 9

// Ví dụ 2: Bỏ qua sản phẩm hết hàng
$san_pham = [
  ["ten" => "Áo", "ton_kho" => 10],
  ["ten" => "Quần", "ton_kho" => 0],
  ["ten" => "Giày", "ton_kho" => 5],
  ["ten" => "Mũ", "ton_kho" => 0]
];

echo "Sản phẩm còn hàng:<br>";
foreach ($san_pham as $sp) {
  if ($sp['ton_kho'] == 0) {
    continue; // Bỏ qua sản phẩm hết hàng
  }
  echo "- " . $sp['ten'] . " (Còn " . $sp['ton_kho'] . ")<br>";
}

/*
Kết quả:
Sản phẩm còn hàng:
- Áo (Còn 10)
- Giày (Còn 5)
*/
?>

BREAK VÀ CONTINUE TRONG VÒNG LẶP BREAK Thoát khỏi vòng lặp ngay lập tức for ($i = 1; $i <= 5; $i++) { if ($i == 3) break; echo $i; } Luồng thực thi: 1 2 3 4 5 THOÁT VÒNG LẶP ✅ Kết quả: 1 2 (Dừng khi gặp 3, không in 3, 4, 5) 💡 Dùng khi: Tìm thấy kết quả, dừng sớm CONTINUE Bỏ qua lần lặp hiện tại, nhảy sang lần tiếp theo for ($i = 1; $i <= 5; $i++) { if ($i == 3) continue; echo $i; } Luồng thực thi: 1 2 3 4 5 Bỏ qua ✅ Kết quả: 1 2 4 5 (Bỏ qua 3, nhưng vòng lặp vẫn chạy tiếp) 💡 Dùng khi: Bỏ qua trường hợp đặc biệt VD: Bỏ qua sản phẩm hết hàng
Hình 3: Break và Continue trong vòng lặp

6.3. Break và Continue với vòng lặp lồng nhau

<?php
// Break với số cấp
for ($i = 1; $i <= 3; $i++) {
  for ($j = 1; $j <= 3; $j++) {
    if ($i == 2 && $j == 2) {
      echo "Dừng tại [$i][$j]<br>";
      break 2; // Thoát cả 2 vòng lặp
    }
    echo "[$i][$j] ";
  }
  echo "<br>";
}

/*
Kết quả:
[1][1] [1][2] [1][3] 
[2][1] Dừng tại [2][2]
*/
?>

7. So sánh các loại vòng lặp

LoạiKhi nào dùngƯu điểmNhược điểm
forBiết trước số lần lặpGọn gàng, tất cả logic ở 1 dòngKhó đọc nếu logic phức tạp
whileKhông biết số lần lặp, phụ thuộc điều kiệnLinh hoạt, dễ hiểuDễ quên tăng biến đếm → vòng lặp vô tận
do-whileCần chạy ít nhất 1 lầnĐảm bảo thực thi 1 lầnÍt dùng, dễ nhầm với while
foreachDuyệt mảngNgắn gọn, không lo indexChỉ dùng được với mảng

8. Lỗi thường gặp và cách tránh

8.1. Vòng lặp vô tận (Infinite Loop)

<?php
// ❌ Sai: Quên tăng biến đếm
$i = 1;
while ($i <= 5) {
  echo $i;
  // Quên: $i++;
}
// → Vòng lặp chạy mãi, crash server

// ✅ Đúng
$i = 1;
while ($i <= 5) {
  echo $i;
  $i++; // Nhớ tăng biến đếm
}
?>

8.2. Điều kiện sai logic

<?php
// ❌ Sai: Dùng = thay vì ==
$i = 0;
while ($i = 10) { // Gán 10 cho $i, luôn true
  echo $i;
  $i++;
}

// ✅ Đúng
$i = 0;
while ($i < 10) { // So sánh
  echo $i;
  $i++;
}
?>

8.3. Sửa mảng trong foreach không dùng tham chiếu

<?php
$diem = [7, 8, 9];

// ❌ Sai: Không sửa được mảng gốc
foreach ($diem as $d) {
  $d += 1; // Chỉ sửa bản sao
}
print_r($diem); // [7, 8, 9] - Không đổi

// ✅ Đúng: Dùng tham chiếu &
foreach ($diem as &$d) {
  $d += 1;
}
print_r($diem); // [8, 9, 10] - Đã đổi
?>

9. Ví dụ tổng hợp

9.1. Tính giai thừa

<?php
$n = 5;
$giai_thua = 1;

for ($i = 1; $i <= $n; $i++) {
  $giai_thua *= $i;
}

echo "$n! = $giai_thua";
// Kết quả: 5! = 120 (5 x 4 x 3 x 2 x 1)
?>

9.2. In tam giác số

<?php
$cao = 5;

for ($i = 1; $i <= $cao; $i++) {
  for ($j = 1; $j <= $i; $j++) {
    echo $j . " ";
  }
  echo "<br>";
}

/*
Kết quả:
1 
1 2 
1 2 3 
1 2 3 4 
1 2 3 4 5
*/
?>

9.3. Tìm số nguyên tố

<?php
function laSoNguyenTo($n) {
  if ($n < 2) return false;
  
  for ($i = 2; $i <= sqrt($n); $i++) {
    if ($n % $i == 0) {
      return false;
    }
  }
  
  return true;
}

echo "Số nguyên tố từ 1 đến 50:<br>";

for ($i = 1; $i <= 50; $i++) {
  if (laSoNguyenTo($i)) {
    echo $i . " ";
  }
}

// Kết quả: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
?>

9.4. Phân trang dữ liệu

<?php
// Giả lập 50 sản phẩm
$tong_san_pham = 50;
$san_pham_moi_trang = 10;
$trang_hien_tai = 3; // Trang 3

$vi_tri_bat_dau = ($trang_hien_tai - 1) * $san_pham_moi_trang;
$vi_tri_ket_thuc = $vi_tri_bat_dau + $san_pham_moi_trang;

echo "<h3>Trang $trang_hien_tai</h3>";

for ($i = $vi_tri_bat_dau; $i < $vi_tri_ket_thuc && $i < $tong_san_pham; $i++) {
  $so_thu_tu = $i + 1;
  echo "Sản phẩm $so_thu_tu<br>";
}

// Tính số trang
$tong_trang = ceil($tong_san_pham / $san_pham_moi_trang);

echo "<br>Trang: ";
for ($p = 1; $p <= $tong_trang; $p++) {
  if ($p == $trang_hien_tai) {
    echo "<strong>$p</strong> ";
  } else {
    echo "<a href='?page=$p'>$p</a> ";
  }
}
?>

Tóm tắt

Qua bài này bạn đã nắm được:

  • Vòng lặp PHP giúp thực thi code lặp đi lặp lại thay vì viết nhiều lần
  • for - Dùng khi biết trước số lần lặp, cú pháp: for (khởi_tạo; điều_kiện; bước_nhảy)
  • while - Lặp khi điều kiện còn đúng, phải nhớ thay đổi điều kiện tránh vòng lặp vô tận
  • do...while - Luôn chạy ít nhất 1 lần, kiểm tra điều kiện ở cuối
  • foreach - Chuyên duyệt mảng, có 2 dạng: foreach ($arr as $val)foreach ($arr as $key => $val)
  • break - Thoát khỏi vòng lặp ngay lập tức
  • continue - Bỏ qua lần lặp hiện tại, nhảy sang lần tiếp theo
  • ✅ Vòng lặp lồng nhau - Dùng cho bảng 2 chiều, tam giác, ma trận
  • ✅ Tránh lỗi: Vòng lặp vô tận, quên tăng biến đếm, dùng = thay ==

Bài tiếp theo, bạn sẽ học về hàm trong PHP để tổ chức code dễ đọc và tái sử dụng.

🎯 Bài tập thực hành

  1. Bài 1: Viết chương trình tính tổng các số từ 1 đến 100 bằng vòng lặp for.
  2. Bài 2: Viết chương trình in bảng cửu chương từ 2 đến 9 (dùng 2 vòng for lồng nhau).
  3. Bài 3: Cho mảng điểm: $diem = [7.5, 8.0, 6.5, 9.0, 5.5, 8.5]. Dùng foreach để:
    • Tính điểm trung bình
    • Đếm số sinh viên đạt loại Giỏi (>= 8.0)
    • Tìm điểm cao nhất

Gợi ý Bài 1:

<?php
$tong = 0;

for ($i = 1; $i <= 100; $i++) {
  $tong += $i;
}

echo "Tổng từ 1 đến 100: $tong";
// Kết quả: 5050
?>

Gợi ý Bài 2:

<?php
for ($bang = 2; $bang <= 9; $bang++) {
  echo "<h4>Bảng cửu chương $bang</h4>";
  
  for ($i = 1; $i <= 10; $i++) {
    $ket_qua = $bang * $i;
    echo "$bang x $i = $ket_qua<br>";
  }
}
?>

Gợi ý Bài 3:

<?php
$diem = [7.5, 8.0, 6.5, 9.0, 5.5, 8.5];

// Tính trung bình
$tong = 0;
foreach ($diem as $d) {
  $tong += $d;
}
$trung_binh = $tong / count($diem);
echo "Điểm TB: " . number_format($trung_binh, 2) . "<br>";

// Đếm số SV giỏi
$so_sv_gioi = 0;
foreach ($diem as $d) {
  if ($d >= 8.0) {
    $so_sv_gioi++;
  }
}
echo "Số SV giỏi: $so_sv_gioi<br>";

// Tìm điểm cao nhất
$diem_max = $diem[0];
foreach ($diem as $d) {
  if ($d > $diem_max) {
    $diem_max = $d;
  }
}
echo "Điểm cao nhất: $diem_max";
?>

Để lại bình luận

Email của bạn sẽ không được hiển thị.