DEV Community

Cover image for 15 PHP Interview Questions You'll Actually Get Asked in 2026
Bikki Singh
Bikki Singh

Posted on • Originally published at codepractice.in

15 PHP Interview Questions You'll Actually Get Asked in 2026

💡 TL;DR

PHP interviews in 2026 aren't about reciting syntax anymore — they're testing whether you know PHP 8's newer features (enums, readonly properties, match), whether you can secure a query against SQL injection, and whether you actually understand why PHP behaves the way it does. Below are 15 questions, fresher round first, senior round after, with runnable code for each.


Why PHP interviews changed

If you last studied PHP a few years back, you learned PHP 5/7 habits that no longer hold up. PHP 8.x shipped enums, readonly properties, and the match expression, and interviewers use these specifically to weed out people who never updated their mental model. On top of that, most "PHP jobs" today are really Laravel jobs, so don't be surprised if dependency injection sneaks into a "pure PHP" interview.

Fresher-round questions

1. What are superglobals?

Built-in arrays available in every scope without needing global. The ones you'll actually touch: $_GET, $_POST, $_SESSION, $_SERVER, $_COOKIE.

$username = $_POST['username'] ?? 'guest'; // null coalescing avoids warnings
$method = $_SERVER['REQUEST_METHOD'];
Enter fullscreen mode Exit fullscreen mode

2. echo vs print

echo takes multiple comma-separated arguments and returns nothing. print takes exactly one argument and returns 1, so it can be used inside an expression.

echo "Hello", " ", "World";
$result = print "Logging in..."; // $result === 1
Enter fullscreen mode Exit fullscreen mode

3. == vs ===

== type-juggles before comparing. === compares value and type. This single distinction causes more PHP bugs than anything else in the language.

var_dump(0 == "abc");   // false in PHP 8+ (was true in PHP 7!)
var_dump("1" == 1);     // true
var_dump("1" === 1);    // false
Enter fullscreen mode Exit fullscreen mode

The 0 == "abc" flip between PHP 7 and 8 trips up a lot of people who learned the language a while ago — worth knowing before someone asks you to explain it live.

4. Removing duplicates from an array

$ids = [101, 102, 101, 103, 102];
$unique = array_values(array_unique($ids)); // [101, 102, 103]
Enter fullscreen mode Exit fullscreen mode

array_unique() filters, array_values() re-indexes so you don't end up with gaps in the keys.

5. include vs require

Both pull in another file's code. include throws a warning and keeps going if the file's missing; require throws a fatal error and stops execution. Use require for anything the app can't function without (DB config), include for optional stuff (footers).

6. Sessions vs cookies

Sessions store data server-side and hand the client a session ID. Cookies store data client-side. That's why sessions are the safer choice for anything sensitive.

session_start();
$_SESSION['user_id'] = 42;      // lives on the server

setcookie('theme', 'dark', time() + 3600, '/'); // lives in the browser
Enter fullscreen mode Exit fullscreen mode

7. The four pillars of OOP

Encapsulation, inheritance, polymorphism, abstraction — expect a follow-up where you have to extend the example with a second subclass.

abstract class Payment {
    abstract public function process(float $amount): string;
}

class CardPayment extends Payment {
    private string $cardNumber;
    public function __construct(string $cardNumber) { $this->cardNumber = $cardNumber; }
    public function process(float $amount): string {
        return "Charged $amount to card ending in " . substr($this->cardNumber, -4);
    }
}
Enter fullscreen mode Exit fullscreen mode

8. Magic methods

Methods prefixed with __ that PHP calls automatically: __construct(), __get()/__set() for intercepting undefined property access, __toString() when an object is coerced to a string.

9. self:: vs static::

self:: always points to the class where the method is defined. static:: follows late static binding — it resolves to whichever class was actually called.

class Base {
    public static function create(): static { return new static(); }
}
class Child extends Base {}

echo get_class(Child::create()); // "Child", not "Base"
Enter fullscreen mode Exit fullscreen mode

Senior-round questions

10. What's actually new in PHP 8

Enums, readonly properties, and match come up constantly.

enum OrderStatus: string {
    case Pending = 'pending';
    case Shipped = 'shipped';
}

class Order {
    public function __construct(
        public readonly string $orderId,
        public OrderStatus $status
    ) {}
}

$order = new Order('ORD-1001', OrderStatus::Pending);
$message = match ($order->status) {
    OrderStatus::Pending => 'Waiting for shipment',
    OrderStatus::Shipped => 'On its way',
};
Enter fullscreen mode Exit fullscreen mode

Try mutating $order->orderId after construction — PHP throws, because that's the entire point of readonly.

11. Preventing SQL injection

The classic failure mode is concatenating user input straight into a query string.

// Bad
$query = "SELECT * FROM users WHERE username = '$username'";

// Good — bound, not concatenated
$stmt = $pdo->prepare("SELECT * FROM users WHERE username = :username");
$stmt->execute(['username' => $username]);
Enter fullscreen mode Exit fullscreen mode

Prepared statements keep the query structure and the data separate, so user input can never rewrite the query's logic — this matters for internal admin tools too, not just public-facing forms.

12. Common design patterns

Singleton and Factory show up most often. Singleton guarantees one instance (often a DB connection); Factory centralizes creation logic. Note the trade-off: singletons carry global state, which makes unit testing harder — many modern codebases prefer dependency injection instead.

13. Performance optimization

Interviewers want specifics, not "make it faster":

  • Turn on OPcache so PHP doesn't recompile scripts every request.
  • Kill N+1 queries — fetch related rows with one query instead of looping and querying per item.
// Bad: one query per order
foreach ($orders as $order) {
    $pdo->query("SELECT * FROM items WHERE order_id = {$order['id']}");
}

// Good: one query total
$stmt = $pdo->query("SELECT * FROM items WHERE order_id IN (" . implode(',', $orderIds) . ")");
Enter fullscreen mode Exit fullscreen mode

14. Dependency injection in Laravel

A class receives its dependencies from outside instead of instantiating them itself; Laravel's service container wires this up automatically.

class OrderController extends Controller {
    public function __construct(private OrderService $orderService) {}
}
Enter fullscreen mode Exit fullscreen mode

15. Abstract classes vs interfaces

An abstract class can mix implemented and unimplemented methods, and a class can only extend one. An interface declares signatures only, and a class can implement several.

Where people lose points

Two recurring mistakes: using loose in_array() comparisons (fix it with the third true argument for strict mode), and creating a fresh PDO connection inside a loop instead of reusing one connection across iterations.

The takeaway

None of this is really about memorization — it's about understanding why PHP does what it does. Pick a few questions above you weren't fully sure about, open a local PHP file, and actually run the code instead of just reading it.

Found this helpful? Check out more at CodePractice Blogs

Top comments (0)