Skip to content
เข้าสู่ระบบ

Loops


Loops ใช้สำหรับทำซ้ำโค้ดหลายรอบ ในบทนี้เราจะเรียนรู้ loops ทุกประเภทใน PHP 8.4+ รวมถึง loop control statements


ใช้เมื่อรู้จำนวนรอบที่ต้องการ:

<?php
// for พื้นฐาน
// for (เริ่มต้น; เงื่อนไข; เพิ่ม/ลด)
for ($i = 0; $i < 5; $i++) {
echo $i . " "; // 0 1 2 3 4
}
// นับถอยหลัง
for ($i = 5; $i >= 1; $i--) {
echo $i . " "; // 5 4 3 2 1
}
// เพิ่มทีละ 2
for ($i = 0; $i <= 10; $i += 2) {
echo $i . " "; // 0 2 4 6 8 10
}
// หลายตัวแปร
for ($i = 0, $j = 10; $i < $j; $i++, $j--) {
echo "($i, $j) "; // (0, 10) (1, 9) (2, 8) (3, 7) (4, 6)
}
// Nested for loop
for ($row = 1; $row <= 3; $row++) {
for ($col = 1; $col <= 3; $col++) {
echo "[$row,$col] ";
}
echo "\n";
}
// [1,1] [1,2] [1,3]
// [2,1] [2,2] [2,3]
// [3,1] [3,2] [3,3]
// Loop กับ array (ใช้ foreach ดีกว่า)
$fruits = ["apple", "banana", "orange"];
for ($i = 0; $i < count($fruits); $i++) {
echo $fruits[$i] . " ";
}
// Optimize: cache count
$count = count($fruits);
for ($i = 0; $i < $count; $i++) {
echo $fruits[$i] . " ";
}
<?php
// สำหรับ templates
?>
<ul>
<?php for ($i = 1; $i <= 5; $i++): ?>
<li>Item <?= $i ?></li>
<?php endfor; ?>
</ul>

ทำซ้ำจนกว่าเงื่อนไขจะเป็น false:

<?php
// while พื้นฐาน
$i = 0;
while ($i < 5) {
echo $i . " "; // 0 1 2 3 4
$i++;
}
// อ่านไฟล์ทีละบรรทัด
$file = fopen("data.txt", "r");
while (!feof($file)) {
$line = fgets($file);
echo $line;
}
fclose($file);
// อ่านจาก database
$stmt = $pdo->query("SELECT * FROM users");
while ($row = $stmt->fetch()) {
echo $row['name'] . "\n";
}
// รอจนกว่าเงื่อนไขจะเปลี่ยน
$attempts = 0;
$maxAttempts = 3;
$success = false;
while ($attempts < $maxAttempts && !$success) {
$success = tryConnection();
if (!$success) {
$attempts++;
sleep(1); // รอ 1 วินาที
}
}
// Infinite loop (ระวัง!)
// while (true) {
// // ต้องมี break เพื่อออก
// }
<?php
$items = ["A", "B", "C"];
$i = 0;
?>
<ul>
<?php while ($i < count($items)): ?>
<li><?= $items[$i] ?></li>
<?php $i++; ?>
<?php endwhile; ?>
</ul>

ทำอย่างน้อย 1 รอบก่อนตรวจเงื่อนไข:

<?php
// do-while - ทำอย่างน้อย 1 ครั้ง
$i = 10;
do {
echo $i . " "; // 10 (แม้เงื่อนไขเป็น false)
$i++;
} while ($i < 5);
// ใช้กับ user input validation
do {
echo "Enter a number (1-10): ";
$input = (int) readline();
} while ($input < 1 || $input > 10);
echo "You entered: $input";
// เปรียบเทียบ while กับ do-while
$value = 10;
// while: ไม่ทำเลย
while ($value < 5) {
echo "while: $value\n"; // ไม่แสดง
$value++;
}
// do-while: ทำ 1 ครั้ง
do {
echo "do-while: $value\n"; // แสดง: do-while: 10
$value++;
} while ($value < 5);

ใช้สำหรับ loop ผ่าน array และ iterable objects:

<?php
// Indexed array
$fruits = ["apple", "banana", "orange"];
foreach ($fruits as $fruit) {
echo $fruit . " "; // apple banana orange
}
// พร้อม index
foreach ($fruits as $index => $fruit) {
echo "$index: $fruit\n";
}
// 0: apple
// 1: banana
// 2: orange
// Associative array
$person = [
"name" => "John",
"age" => 25,
"city" => "Bangkok"
];
foreach ($person as $key => $value) {
echo "$key: $value\n";
}
// name: John
// age: 25
// city: Bangkok
// Nested arrays
$users = [
["name" => "Alice", "age" => 30],
["name" => "Bob", "age" => 25],
["name" => "Charlie", "age" => 35],
];
foreach ($users as $user) {
echo "{$user['name']} is {$user['age']} years old\n";
}
// Destructuring (PHP 7.1+)
foreach ($users as ["name" => $name, "age" => $age]) {
echo "$name is $age years old\n";
}
<?php
$numbers = [1, 2, 3, 4, 5];
// ❌ การแก้ไขแบบนี้ไม่มีผล
foreach ($numbers as $num) {
$num = $num * 2; // $num เป็น copy
}
print_r($numbers); // ยังเป็น [1, 2, 3, 4, 5]
// ✅ ใช้ reference (&) เพื่อแก้ไข
foreach ($numbers as &$num) {
$num = $num * 2; // แก้ไขตรงๆ
}
unset($num); // สำคัญ! ควร unset หลังใช้ reference
print_r($numbers); // [2, 4, 6, 8, 10]
// ✅ หรือใช้ key เพื่อแก้ไข
foreach ($numbers as $key => $num) {
$numbers[$key] = $num + 1;
}
<?php
$products = [
["name" => "iPhone", "price" => 35000],
["name" => "Samsung", "price" => 25000],
];
?>
<table>
<tr><th>Product</th><th>Price</th></tr>
<?php foreach ($products as $product): ?>
<tr>
<td><?= $product['name'] ?></td>
<td><?= number_format($product['price']) ?></td>
</tr>
<?php endforeach; ?>
</table>

ใช้ออกจาก loop ทันที:

<?php
// break ออกจาก loop
for ($i = 1; $i <= 10; $i++) {
if ($i === 5) {
break; // ออกเมื่อ $i = 5
}
echo $i . " "; // 1 2 3 4
}
// break กับ nested loops
for ($i = 1; $i <= 3; $i++) {
for ($j = 1; $j <= 3; $j++) {
if ($j === 2) {
break; // ออกจาก inner loop เท่านั้น
}
echo "($i,$j) ";
}
}
// (1,1) (2,1) (3,1)
// break หลายระดับ
for ($i = 1; $i <= 3; $i++) {
for ($j = 1; $j <= 3; $j++) {
if ($i === 2 && $j === 2) {
break 2; // ออกจาก 2 loops
}
echo "($i,$j) ";
}
}
// (1,1) (1,2) (1,3) (2,1)
// break กับ switch (สำคัญ!)
foreach ($items as $item) {
switch ($item) {
case "stop":
break 2; // ออกจาก foreach ไม่ใช่ switch!
default:
echo $item;
}
}

ใช้ข้ามไปยังรอบถัดไป:

<?php
// ข้ามเลขคู่
for ($i = 1; $i <= 10; $i++) {
if ($i % 2 === 0) {
continue; // ข้ามเลขคู่
}
echo $i . " "; // 1 3 5 7 9
}
// ข้ามค่าว่าง
$names = ["Alice", "", "Bob", null, "Charlie"];
foreach ($names as $name) {
if (empty($name)) {
continue;
}
echo "$name\n";
}
// Alice
// Bob
// Charlie
// continue หลายระดับ
for ($i = 1; $i <= 3; $i++) {
for ($j = 1; $j <= 3; $j++) {
if ($j === 2) {
continue 2; // ข้ามไปรอบถัดไปของ outer loop
}
echo "($i,$j) ";
}
}
// (1,1) (2,1) (3,1)

ข้ามไปยัง label (ใช้น้อยมาก):

<?php
// goto - ไม่แนะนำ
for ($i = 0; $i < 10; $i++) {
for ($j = 0; $j < 10; $j++) {
if ($i * $j >= 25) {
goto end;
}
echo "$i * $j = " . ($i * $j) . "\n";
}
}
end:
echo "Done!";
// ❌ ไม่สามารถ goto เข้าไปใน loop ได้
// goto inside;
// for ($i = 0; $i < 5; $i++) {
// inside: // Error!
// echo $i;
// }

หลีกเลี่ยง goto

goto ทำให้โค้ดอ่านยากและ debug ยาก ใช้ break พร้อมระบุระดับแทน หรือ restructure โค้ดให้ไม่ต้องใช้


PHP รองรับ Iterator pattern:

<?php
// Generators
function range_generator(int $start, int $end) {
for ($i = $start; $i <= $end; $i++) {
yield $i;
}
}
foreach (range_generator(1, 5) as $num) {
echo $num . " "; // 1 2 3 4 5
}
// Generator กับ key => value
function items_generator() {
yield "a" => 1;
yield "b" => 2;
yield "c" => 3;
}
foreach (items_generator() as $key => $value) {
echo "$key: $value\n";
}
// DirectoryIterator
$dir = new DirectoryIterator("./");
foreach ($dir as $file) {
if ($file->isFile()) {
echo $file->getFilename() . "\n";
}
}
// ArrayIterator
$iterator = new ArrayIterator(["a", "b", "c"]);
foreach ($iterator as $value) {
echo $value . " ";
}

บ่อยครั้งใช้ array functions แทน loop ได้:

<?php
$numbers = [1, 2, 3, 4, 5];
// แทน for loop ที่ transform ข้อมูล
// ❌ Loop
$doubled = [];
foreach ($numbers as $n) {
$doubled[] = $n * 2;
}
// ✅ array_map
$doubled = array_map(fn($n) => $n * 2, $numbers);
// [2, 4, 6, 8, 10]
// แทน for loop ที่ filter
// ❌ Loop
$evens = [];
foreach ($numbers as $n) {
if ($n % 2 === 0) {
$evens[] = $n;
}
}
// ✅ array_filter
$evens = array_filter($numbers, fn($n) => $n % 2 === 0);
// [2, 4]
// แทน for loop ที่ reduce
// ❌ Loop
$sum = 0;
foreach ($numbers as $n) {
$sum += $n;
}
// ✅ array_reduce
$sum = array_reduce($numbers, fn($acc, $n) => $acc + $n, 0);
// 15
// หรือใช้ array_sum
$sum = array_sum($numbers);
// 15
// รวม map + filter
$result = array_filter(
array_map(fn($n) => $n * 2, $numbers),
fn($n) => $n > 4
);
// [6, 8, 10]
  • Declarative - บอกว่าทำอะไร ไม่ใช่ทำยังไง
  • No mutation - สร้าง array ใหม่ ไม่แก้ของเดิม
  • Chainable - ต่อกันได้
  • Testable - test ง่ายกว่า

<?php
$scores = [85, 92, 78, 95, 88];
// วิธี loop
$sum = 0;
foreach ($scores as $score) {
$sum += $score;
}
$average = $sum / count($scores);
// วิธี function
$sum = array_sum($scores);
$average = $sum / count($scores);
echo "Sum: $sum, Average: $average";
// Sum: 438, Average: 87.6
<?php
$users = [
["id" => 1, "name" => "Alice", "active" => true],
["id" => 2, "name" => "Bob", "active" => false],
["id" => 3, "name" => "Charlie", "active" => true],
];
// หา user ที่ active = false คนแรก
$found = null;
foreach ($users as $user) {
if (!$user["active"]) {
$found = $user;
break; // หาเจอแล้ว ออก
}
}
// หรือใช้ array_filter + reset
$inactive = array_filter($users, fn($u) => !$u["active"]);
$found = reset($inactive) ?: null;
echo $found["name"]; // "Bob"
<?php
$products = [
["name" => "iPhone", "category" => "phone"],
["name" => "Galaxy", "category" => "phone"],
["name" => "MacBook", "category" => "laptop"],
["name" => "XPS", "category" => "laptop"],
];
// Group by category
$grouped = [];
foreach ($products as $product) {
$category = $product["category"];
$grouped[$category][] = $product;
}
print_r($grouped);
// [
// "phone" => [["name" => "iPhone", ...], ["name" => "Galaxy", ...]],
// "laptop" => [["name" => "MacBook", ...], ["name" => "XPS", ...]]
// ]
<?php
$items = range(1, 100); // 1-100
$page = 3;
$perPage = 10;
// หา offset
$offset = ($page - 1) * $perPage;
// ตัด array
$pageItems = array_slice($items, $offset, $perPage);
// [21, 22, 23, 24, 25, 26, 27, 28, 29, 30]
// คำนวณจำนวนหน้า
$totalPages = ceil(count($items) / $perPage);
// 10

<?php
// 1. Cache array length
// ❌ Slow
for ($i = 0; $i < count($array); $i++) { }
// ✅ Fast
$count = count($array);
for ($i = 0; $i < $count; $i++) { }
// 2. ใช้ foreach แทน for index
// ❌ Slower
for ($i = 0; $i < count($array); $i++) {
echo $array[$i];
}
// ✅ Faster
foreach ($array as $item) {
echo $item;
}
// 3. หลีกเลี่ยง function call ใน loop
// ❌ Slow
foreach ($items as $item) {
$result = someExpensiveFunction($item); // เรียกทุกรอบ
}
// ✅ Fast (ถ้า memoize ได้)
$cache = [];
foreach ($items as $item) {
$key = getKey($item);
if (!isset($cache[$key])) {
$cache[$key] = someExpensiveFunction($item);
}
$result = $cache[$key];
}
// 4. ใช้ break เมื่อเจอแล้ว
foreach ($items as $item) {
if ($item === $target) {
$found = $item;
break; // ไม่ต้อง loop ต่อ
}
}

แบบฝึกหัดที่ 1: FizzBuzz

Section titled “แบบฝึกหัดที่ 1: FizzBuzz”
<?php
function fizzBuzz(int $n): void {
for ($i = 1; $i <= $n; $i++) {
$output = match(true) {
$i % 15 === 0 => "FizzBuzz",
$i % 3 === 0 => "Fizz",
$i % 5 === 0 => "Buzz",
default => (string) $i,
};
echo "$output\n";
}
}
fizzBuzz(15);

แบบฝึกหัดที่ 2: Prime Numbers

Section titled “แบบฝึกหัดที่ 2: Prime Numbers”
<?php
function isPrime(int $n): bool {
if ($n < 2) return false;
if ($n === 2) return true;
if ($n % 2 === 0) return false;
for ($i = 3; $i <= sqrt($n); $i += 2) {
if ($n % $i === 0) {
return false;
}
}
return true;
}
function getPrimes(int $limit): array {
$primes = [];
for ($i = 2; $i <= $limit; $i++) {
if (isPrime($i)) {
$primes[] = $i;
}
}
return $primes;
}
print_r(getPrimes(50));
// [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

แบบฝึกหัดที่ 3: Flatten Array

Section titled “แบบฝึกหัดที่ 3: Flatten Array”
<?php
function flatten(array $array): array {
$result = [];
foreach ($array as $item) {
if (is_array($item)) {
$result = [...$result, ...flatten($item)];
} else {
$result[] = $item;
}
}
return $result;
}
$nested = [1, [2, 3], [[4, 5], 6], 7];
print_r(flatten($nested));
// [1, 2, 3, 4, 5, 6, 7]

ในบทนี้เราได้เรียนรู้:

  • for loop สำหรับรู้จำนวนรอบ
  • while และ do-while สำหรับ loop จนกว่าเงื่อนไขจะเปลี่ยน
  • foreach สำหรับ loop ผ่าน arrays และ iterables
  • break, continue และ goto
  • Generators และ Iterators
  • Array functions ที่ใช้แทน loops
  • Common patterns และ performance tips

1. ใช้ foreach แทน for กับ arrays

Section titled “1. ใช้ foreach แทน for กับ arrays”
<?php
// แนะนำ
foreach ($items as $item) {
process($item);
}
// ไม่แนะนำ
for ($i = 0; $i < count($items); $i++) {
process($items[$i]);
}

2. หลีกเลี่ยง Infinite Loops

Section titled “2. หลีกเลี่ยง Infinite Loops”
<?php
// อันตราย: ไม่มีทางออก
// while (true) { }
// ปลอดภัย: มี break condition
$maxIterations = 1000;
$i = 0;
while (true) {
if ($i++ >= $maxIterations) break;
// do something
}
<?php
foreach ($items as &$item) {
$item = process($item);
}
unset($item); // สำคัญมาก!

แหล่งข้อมูลเพิ่มเติม

Section titled “แหล่งข้อมูลเพิ่มเติม”

เข้าสู่ระบบเพื่อดูเนื้อหาเต็ม

ยืนยันตัวตนด้วยบัญชี Google เพื่อปลดล็อกบทความทั้งหมด