Skip to content

PHP Tutorial PHP Interview and Practice Challenge

Debugging Challenges

Lesson 368 of 369 2 min read By Deepak Paswan Updated Oct 5, 2026

Each snippet below has a bug. Predict what goes wrong, then check the solution. Real debugging is the same: predict, run, compare.

Bug 1: the missing first item

index.php
PHP
<?php
$items = ["pen", "book", "bag"];

for ($i = 1; $i < count($items); $i++) {
    echo $items[$i] . " ";
}

What is printed, and what was intended?

Show the answer

It prints book bag. The loop starts at 1, but array positions start at 0. Fix: $i = 0, or use foreach ($items as $item).

index.php
PHP
<?php
foreach (["pen", "book", "bag"] as $item) {
    echo $item . " ";
}
Output
OUTPUT
pen book bag

Bug 2: “Not found”

index.php
PHP
<?php
$email = "ana@example.com";

if (strpos($email, "ana") == false) {
    echo "Not found";
} else {
    echo "Found";
}
Show the answer

strpos() returns 0 (the position), and 0 == false is true. Use ===, or str_contains().

index.php
PHP
<?php
$email = "ana@example.com";

echo str_contains($email, "ana") ? "Found" : "Not found";
Output
OUTPUT
Found

Bug 3: the last item changes

index.php
PHP
<?php
$list = [1, 2, 3];

foreach ($list as &$v) {
}

foreach ($list as $v) {
}

echo implode(",", $list);
Show the answer

The output is 1,2,2. After the first loop, $v is still a reference to the last element, so the second loop writes each value into it. Fix: unset($v); after the first loop, or avoid references.

index.php
PHP
<?php
$list = [1, 2, 3];

foreach ($list as &$v) {
}
unset($v);

foreach ($list as $v) {
}

echo implode(",", $list);
Output
OUTPUT
1,2,3

Bug 4: the total is always 0

index.php
PHP
<?php
$total = 0;

function addToTotal(int $amount): void
{
    $total += $amount;
}

addToTotal(5);
addToTotal(10);

echo $total;
Show the answer

The function works on its own local $total (and PHP warns about an undefined variable). Return the new value instead:

index.php
PHP
<?php
function addToTotal(int $total, int $amount): int
{
    return $total + $amount;
}

$total = 0;
$total = addToTotal($total, 5);
$total = addToTotal($total, 10);

echo $total;
Output
OUTPUT
15

Bug 5: the greeting shows markup

index.php
PHP
<?php
$name = $_GET["name"] ?? "guest";

echo "<h1>Hello, $name</h1>";

What is wrong with it?

Show the answer

XSS. ?name=<script>... runs script in the visitor’s browser. Escape output:

index.php
PHP
<?php
$name = '<script>alert(1)</script>';

echo "<h1>Hello, " . htmlspecialchars($name, ENT_QUOTES, "UTF-8") . "</h1>";
Output
OUTPUT
<h1>Hello, &lt;script&gt;alert(1)&lt;/script&gt;</h1>

Bug 6: the price is wrong

index.php
PHP
<?php
$price = "19.99";
$quantity = "3";

echo $price * $quantity . " " . ($price * $quantity == 59.97 ? "exact" : "not exact");

What does it print, and why is it risky?

Show the answer

It prints 59.97 not exact. Floating-point numbers are approximate, so 19.99 * 3 is not exactly 59.97. Do money calculations with integers (cents) or BCMath, and compare floats with a tolerance.

index.php
PHP
<?php
$cents = 1999 * 3;

echo number_format($cents / 100, 2) . " " . ($cents === 5997 ? "exact" : "not exact");
Output
OUTPUT
59.97 exact

Bug 7: “headers already sent”

index.php
PHP
<?php
echo "Welcome!";
header("Location: /dashboard");
exit;
Show the answer

header() must be called before any output. echo already sent the body. Remove the output (or buffer it with ob_start()), and check for stray whitespace or a byte order mark before <?php in included files.

index.php
PHP
<?php
header("Location: /dashboard");
exit;

Bug 8: users see each other’s data

index.php
PHP
<?php
$id = $_GET["id"];
$order = $pdo->query("SELECT * FROM orders WHERE id = $id")->fetch();

Name two problems.

Show the answer
  1. SQL injection (the id is joined into the SQL).
  2. IDOR (no check that the order belongs to the logged-in user).
index.php
PHP
<?php
$id = filter_var($_GET["id"] ?? null, FILTER_VALIDATE_INT);
$stmt = $pdo->prepare("SELECT id, total FROM orders WHERE id = :id AND user_id = :user");
$stmt->execute(["id" => $id, "user" => $_SESSION["user_id"]]);
$order = $stmt->fetch();

Bug 9: the names are in the wrong order

index.php
PHP
<?php
$names = ["ben", "Cara", "ana", "Dev"];
sort($names);

echo implode(", ", $names);

The list should be alphabetical, ignoring case. What is printed?

Show the answer

It prints Cara, Dev, ana, ben. By default sort() compares strings byte by byte, so every capital letter comes before every small letter. Ask for a case-insensitive sort:

index.php
PHP
<?php
$names = ["ben", "Cara", "ana", "Dev"];

sort($names, SORT_STRING | SORT_FLAG_CASE);

echo implode(", ", $names);
Output
OUTPUT
ana, ben, Cara, Dev

For human-friendly sorting of numbers inside text (file2, file10), use natcasesort() or SORT_NATURAL.

Bug 10: the cart is empty after redirect

index.php
PHP
<?php
$cart = ["pen"];
header("Location: cart.php");
exit;
// cart.php: var_dump($cart);
Show the answer

Variables do not survive a redirect: each request starts fresh. Store the cart in the session (or the database).

index.php
PHP
<?php
session_start();
$_SESSION["cart"] = ["pen"];
header("Location: cart.php");
exit;