Interview Q&A · 99 questions · 25 answered publicly

PHP 7 Interview Questions

Ordered by how often they're asked. Sign in free to see every answer, rate your confidence and run timed mock interviews.

  1. Most asked What were the headline improvements of PHP 7.0 over PHP 5.6?

    Summary

    PHP 7.0 roughly doubled performance and cut memory use thanks to the PHPNG engine rewrite, and added scalar type declarations, return types, ??, <=>, anonymous classes and the Throwable error hierarchy.

    Longer Answer

    The new engine (PHPNG, Zend Engine 3) reorganized internal data structures: zvals no longer need separate heap allocation for scalars, and hash tables became more compact. Real-world apps like WordPress served about twice as many requests per second.

    Language-wise, PHP 7 introduced optional scalar type hints (int, float, string, bool), return type declarations, declare(strict_types=1), the null coalescing and spaceship operators, anonymous classes, random_bytes()/random_int(), and turned most fatal errors into catchable Error exceptions. The old mysql_* extension and ereg functions were removed.

    Key Points

    • ~2x throughput, lower memory (PHPNG)
    • Scalar and return types, strict_types
    • ??, <=>, anonymous classes
    • Fatal errors become Error exceptions
    • Removed mysql_*, ereg, ASP tags

    Permalink

  2. Most asked Explain scalar type declarations and coercive vs strict mode in PHP 7.

    Summary

    PHP 7 allows int, float, string and bool parameter types. By default (coercive mode) compatible values are converted, e.g. '5' → 5; with declare(strict_types=1) mismatches throw TypeError.

    Longer Answer

    In coercive mode, function add(int $a) called with '5' works, and with '5 apples' emits a notice in 7.x. With strict types, only an exact type match is accepted, except that an int may be passed to a float parameter.

    Strict mode is decided by the calling file, which lets libraries adopt types without breaking callers.

    Code Example

    <?php
    declare(strict_types=1);
    
    function add(int $a, int $b): int
    {
        return $a + $b;
    }
    
    add(1, 2);     // 3
    add('1', 2);   // TypeError in strict mode
    

    Key Points

    • Types: int, float, string, bool
    • Coercive by default
    • strict_types=1 per file, caller-decided
    • Only int → float widening allowed in strict mode

    Permalink

  3. Most asked How do return type declarations work in PHP 7?

    Summary

    You can append : type to a function to declare what it returns; PHP checks (and in coercive mode converts) the returned value, throwing TypeError on mismatch.

    Longer Answer

    PHP 7.0 allowed scalar, array, callable, class and self return types. PHP 7.1 added nullable (?string) and void, and 7.2 added object. A method overriding a parent must keep a compatible return type (covariance only fully arrived in 7.4).

    Key Points

    • function f(): int
    • ?T nullable and void in 7.1
    • object in 7.2
    • Full covariance in 7.4

    Permalink

  4. Most asked What does the null coalescing operator `??` do, and how is it different from `isset()` with a ternary?

    Summary

    $a ?? $b returns $a if it exists and isn't null, otherwise $b, without emitting notices. It's shorthand for isset($a) ? $a : $b.

    Longer Answer

    It works with nested array keys and object properties: $config['db']['host'] ?? 'localhost'. It can be chained ($a ?? $b ?? $c). PHP 7.4 added the assignment form ??=. Unlike ?:, it doesn't treat 0, '' or false as missing.

    Code Example

    <?php
    $page = $_GET['page'] ?? 1;
    $host = $config['db']['host'] ?? getenv('DB_HOST') ?? 'localhost';
    $options['timeout'] ??= 30; // PHP 7.4
    

    Key Points

    • Equivalent to isset($x) ? $x : $default
    • No undefined index notices
    • Chainable
    • ??= (7.4) assigns if null

    Permalink

  5. Most asked Explain the `Throwable`, `Error` and `Exception` hierarchy introduced in PHP 7.

    Summary

    PHP 7 made most fatal errors catchable by throwing Error objects. Both Error and Exception implement the new Throwable interface, but Error does not extend Exception.

    Longer Answer

    Subclasses of Error include TypeError, ParseError, ArithmeticError, DivisionByZeroError and ArgumentCountError (7.1). Old catch (Exception $e) blocks don't catch them, which is intentional to preserve BC. Catch Throwable at top-level handlers. User classes can't implement Throwable directly; extend Exception instead.

    Code Example

    <?php
    try {
        intdiv(1, 0);
    } catch (DivisionByZeroError $e) {
        echo 'Cannot divide: ', $e->getMessage();
    } catch (Throwable $e) {
        error_log((string) $e);
    }
    

    Key Points

    • Throwable → Error, Exception
    • catch (Exception) doesn't catch Error
    • Catch Throwable in global handlers
    • set_exception_handler receives Throwable in 7+

    Permalink

  6. Most asked What are nullable types in PHP 7.1?

    Summary

    Prefixing a type with ? (e.g. ?string) allows the value to be either that type or null, for parameters and return types.

    Longer Answer

    Before 7.1 the only way to accept null was a = null default, which also made the parameter optional. ?string $name is required but may be null. (Implicit nullability via = null defaults was deprecated in PHP 8.4.)

    Code Example

    <?php
    function findUser(int $id): ?User
    {
        return $this->users[$id] ?? null;
    }
    
    function greet(?string $name): string
    {
        return 'Hello ' . ($name ?? 'guest');
    }
    

    Key Points

    • ?T means T or null
    • Different from an optional parameter
    • Works for params and return types
    • Typed properties (7.4) also support ?T

    Permalink

  7. Most asked What are typed properties in PHP 7.4?

    Summary

    PHP 7.4 lets class properties declare types (public int $id;), enforced on every write; an uninitialized typed property throws an Error when read.

    Longer Answer

    Typed properties start in an uninitialized state rather than null, unless given a default. Reading before assignment throws "must not be accessed before initialization". Nullable types need an explicit = null default if you want null initially. All types except void and callable are supported, and strict_types affects writes like parameters.

    Code Example

    <?php
    class User
    {
        public int $id;
        public string $email;
        public ?DateTimeImmutable $verifiedAt = null;
        public array $roles = [];
    }
    
    $u = new User();
    echo $u->email; // Error: must not be accessed before initialization
    

    Key Points

    • private ?string $name = null;
    • Uninitialized ≠ null
    • No void or callable property types
    • Writes are type-checked

    Permalink

  8. Most asked What are arrow functions in PHP 7.4 and how do they differ from closures?

    Summary

    Arrow functions fn($x) => expr are single-expression closures that automatically capture outer variables by value, with no use clause needed.

    Longer Answer

    They're ideal for short callbacks in array_map, array_filter and usort. Limitations: one expression only (no statements), and captured variables are by value, so they can't modify outer variables. They also auto-bind $this in class context (use static fn to avoid that).

    Code Example

    <?php
    $factor = 3;
    $tripled = array_map(fn($n) => $n * $factor, [1, 2, 3]); // [3, 6, 9]
    
    // Equivalent closure:
    $tripled = array_map(function ($n) use ($factor) { return $n * $factor; }, [1, 2, 3]);
    

    Key Points

    • fn($x) => $x * $factor
    • Auto-capture by value
    • Single expression only
    • Can't mutate outer variables

    Permalink

  9. Most asked What are the main breaking changes when upgrading from PHP 7.4 to 8.0?

    Summary

    Key breaks: saner string/number comparisons, many internal-function warnings became TypeError/ValueError, removal of 7.x-deprecated features, PHP 4 constructors removed, stricter arithmetic on arrays/objects, and changed default error reporting.

    Longer Answer

    Other notable changes:

    • match and mixed became reserved keywords.
    • Private methods are no longer inheritance-checked against parent signatures, while abstract trait method signatures are now checked.
    • @ no longer silences fatal errors.
    • Sorting became stable.
    • Resource handles turned into objects for curl, GD, sockets, XML and more, so is_resource() checks break.
    • create_function(), each() and money_format() were removed.

    Tooling such as Rector, PHPStan and PHPCompatibility automates most of the detection.

    Key Points

    • 0 == 'a' now false
    • Internal functions throw TypeError/ValueError
    • Resources → objects (curl, GD, ...)
    • Removed functions: each, create_function
    • Use Rector + PHPCompatibility

    Permalink

  10. Most asked What does the spaceship operator `<=>` return and where is it used?

    Summary

    $a <=> $b returns -1, 0 or 1 when $a is less than, equal to, or greater than $b, which makes it ideal for usort comparators.

    Longer Answer

    It works on integers, floats, strings and arrays using PHP's standard comparison rules. For multi-key sorts, compare arrays: [$a->last, $a->first] <=> [$b->last, $b->first].

    Code Example

    <?php
    usort($people, fn($a, $b) => [$a['last'], $a['first']] <=> [$b['last'], $b['first']]);
    // before 7.4 arrow functions:
    usort($nums, function ($a, $b) { return $b <=> $a; }); // descending
    

    Key Points

    • Returns -1, 0, or 1
    • Perfect for usort/uasort callbacks
    • Compare arrays for multi-column sorting

    Permalink

  11. Most asked What does the `void` return type mean?

    Summary

    void (PHP 7.1) declares a function returns nothing; it may use a bare return; but not return null; or any value.

    Longer Answer

    It documents side-effect-only functions such as setters, event handlers and loggers. Calling a void function still yields null to the caller. void cannot be nullable or part of a union.

    Key Points

    • Bare return; allowed, no value
    • return null; is a compile error
    • Caller receives null

    Permalink

  12. Most asked What is multi-catch exception handling in PHP 7.1?

    Summary

    A single catch block can handle several exception types separated by |, e.g. catch (InvalidArgumentException | LengthException $e).

    Longer Answer

    It removes duplicated catch bodies when different exceptions need identical handling. The caught variable's type is the union; use instanceof if you must distinguish. Order still matters: the first matching block wins.

    Code Example

    <?php
    try {
        $client->send($request);
    } catch (ConnectException | TimeoutException $e) {
        $this->retryLater($request, $e);
    }
    

    Key Points

    • catch (A | B $e)
    • Removes duplicated handlers
    • First matching block wins

    Permalink

  13. Most asked Compare PDO and mysqli.

    Summary

    PDO is a database-agnostic abstraction supporting a dozen drivers with named placeholders; mysqli is MySQL-specific with access to MySQL-only features. Both support prepared statements.

    Longer Answer

    PDO: named parameters (:id), a consistent API across databases, flexible fetch modes (FETCH_CLASS), and exceptions via ERRMODE_EXCEPTION (the default since PHP 8.0). mysqli: positional ? only, procedural and OO APIs, async queries and multi-statements. Most modern projects use PDO (directly or through an ORM).

    Key Points

    • PDO: multi-DB, named params
    • mysqli: MySQL-only features
    • Both support prepared statements
    • Exceptions mode recommended

    Comparison / Tradeoffs

    PDO mysqli
    Databases 12+ drivers MySQL/MariaDB
    Placeholders Named and positional Positional
    API OO OO + procedural

    Permalink

  14. Most asked What are type-juggling vulnerabilities in PHP 7 and how do you prevent them?

    Summary

    In PHP 7, loose comparison (==) converts types unpredictably: '0e123' == '0e456' is true (both read as 0 in scientific notation) and 0 == 'abc' is true. This enables authentication bypasses with 'magic hashes'. Always use === and hash_equals().

    Longer Answer

    Classic bug: if (md5($input) == $storedHash), where both hashes start with 0e followed by digits, so they compare equal as floats (0). Also in_array, array_search and switch use loose comparison by default. Use strict comparison, strict flags and timing-safe hash_equals() for secrets.

    Key Points

    • '0e1' == '0e2' is true (numeric strings)
    • 0 == 'abc' true in PHP 7
    • Use ===, in_array(..., true)
    • hash_equals() for token comparison

    Permalink

  15. Most asked What is the difference between `==` and `===` in PHP?

    Summary

    == compares values after type juggling; === compares both value and type without conversion.

    Longer Answer

    '1' == 1 is true but '1' === 1 is false. For objects, == checks same class and equal properties, while === checks it's the same instance. Prefer === by default; it's clearer and avoids security bugs.

    Key Points

    • == loose, converts types
    • === strict, no conversion
    • Objects: === means same instance

    Permalink

  16. Most asked Explain `public`, `protected` and `private` visibility in PHP.

    Summary

    public members are accessible everywhere, protected members within the class and its subclasses, and private members only within the declaring class.

    Longer Answer

    Visibility in PHP is class-based, not object-based: an object can access private members of another instance of the same class (useful in equals() methods). Prefer the narrowest visibility; private + final classes reduce the API surface you must maintain.

    Key Points

    • Public → anywhere
    • Protected → class hierarchy
    • Private → declaring class only
    • Class-based, not instance-based

    Permalink

  17. Most asked What are traits and when were they introduced?

    Summary

    Traits (PHP 5.4) are reusable sets of methods and properties that are copied into classes with use, providing horizontal code reuse without inheritance.

    Longer Answer

    They're useful for cross-cutting behavior (timestamps, soft deletes in Eloquent). Overuse leads to hidden dependencies, because traits often assume host-class properties. Conflicts are resolved with insteadof and as.

    Key Points

    • Compile-time copy-paste into classes
    • Not a type, so can't type-hint
    • Can declare abstract methods to require host members

    Permalink

  18. Most asked How does `spl_autoload_register()` work, and why was `__autoload()` deprecated?

    Summary

    spl_autoload_register() adds a callback to a stack of autoloaders that PHP calls when an unknown class is referenced; __autoload() allowed only a single global function, so libraries conflicted. It was deprecated in 7.2 and removed in 8.0.

    Longer Answer

    Composer registers its own loader via spl_autoload_register. Multiple loaders can coexist and are tried in order. Autoloaders should not throw when a class isn't found, so the next loader gets a chance.

    Key Points

    • Stack of autoloaders
    • Composer uses it under the hood
    • __autoload deprecated 7.2, removed 8.0

    Permalink

  19. Most asked What is the difference between `isset()`, `empty()` and `is_null()`?

    Summary

    isset() is true if a variable exists and isn't null; empty() is true if it doesn't exist or is falsy; is_null() is true only for null and warns on undefined variables.

    Longer Answer

    empty('0') is true, a common bug for numeric form input. isset() and empty() are language constructs that don't emit notices for undefined variables or keys. isset($arr['k']) is false when the key exists with a null value; use array_key_exists() to distinguish.

    Key Points

    • isset: exists and not null
    • empty: missing or falsy ('0', 0, '', [], null, false)
    • is_null: strictly null
    • array_key_exists for null-valued keys

    Comparison / Tradeoffs

    Value isset empty is_null
    null false true true
    '' true true false
    '0' true true false
    [] true true false

    Permalink

  20. Most asked How do references (`&`) work in PHP?

    Summary

    A reference makes two names point to the same variable container, so changing one changes the other. You can assign by reference, pass by reference (function f(&$x)), and return by reference.

    Longer Answer

    References are not pointers; you can't do arithmetic on them. Objects don't need references to be modified inside functions, because object handles are already shared. Overusing references hurts readability and can defeat copy-on-write. A classic bug is the dangling reference after foreach ($arr as &$v).

    Code Example

    <?php
    function addTax(array &$prices, float $rate): void
    {
        foreach ($prices as &$p) {
            $p *= (1 + $rate);
        }
        unset($p);
    }
    

    Key Points

    • Aliases to the same value container
    • Objects are already passed by handle
    • Unset loop references after foreach
    • Prefer return values over by-ref params

    Permalink

  21. Most asked What is the difference between assigning an object and cloning it?

    Summary

    Assigning an object copies the handle, so both variables refer to the same object; clone creates a new object with copied properties (shallow), and calls __clone() for customization.

    Longer Answer

    With a shallow clone, nested objects are still shared. Implement __clone() to deep-copy them: $this->address = clone $this->address;. Immutable objects avoid this problem entirely.

    Key Points

    • Assignment shares the object
    • clone is shallow
    • __clone() for deep copies
    • Immutability sidesteps aliasing

    Permalink

  22. Most asked How do PHP sessions work under the hood?

    Summary

    session_start() reads a session ID from a cookie (default PHPSESSID), loads serialized data from the save handler (files by default) into $_SESSION, and writes it back at request end, holding a lock in between.

    Longer Answer

    Default file sessions live in session.save_path, and garbage collection is probabilistic (gc_probability/gc_divisor, gc_maxlifetime). The file lock serializes concurrent requests from the same user. Harden with use_strict_mode, cookie_secure, cookie_httponly and cookie_samesite, and regenerate IDs on login.

    Key Points

    • Cookie ID → server-side data
    • File locks serialize concurrent requests
    • Probabilistic GC
    • Harden cookie flags, regenerate on login

    Permalink

  23. Most asked What is the difference between `array_merge()` and the `+` operator on arrays?

    Summary

    array_merge() appends and renumbers integer keys, while string keys from later arrays overwrite earlier ones. + keeps the left array's keys and only adds keys that don't already exist.

    Longer Answer

    [0 => 'a'] + [0 => 'b'] gives [0 => 'a']; array_merge([0 => 'a'], [0 => 'b']) gives ['a', 'b']. + is handy for applying defaults: $options + $defaults. array_replace() overwrites by key without renumbering.

    Key Points

    • array_merge: renumber ints, overwrite strings
    • +: left wins, nothing renumbered
    • $options + $defaults for defaults
    • array_replace overwrites by key

    Permalink

  24. Most asked Explain the MVC pattern as used in PHP frameworks.

    Summary

    MVC separates the Model (data and business rules), the View (presentation templates) and the Controller (handles the HTTP request, calls models/services, chooses a view).

    Longer Answer

    A front controller (public/index.php) receives every request, a router maps it to a controller action, and the response is rendered. Keep controllers thin by moving business logic into services or domain models, so it can be reused from CLI or queues.

    Key Points

    • Front controller + router
    • Thin controllers
    • Business logic in models/services
    • Views only format output

    Permalink

  25. Most asked What is the difference between running PHP as mod_php and PHP-FPM?

    Summary

    mod_php embeds PHP inside every Apache process, while PHP-FPM is a separate FastCGI process manager that web servers like Nginx or Apache (mod_proxy_fcgi) talk to.

    Longer Answer

    With mod_php, every Apache worker carries PHP's memory even when serving static files, and it requires the prefork MPM. FPM separates concerns: Nginx serves static files efficiently, and FPM pools can run under different users with independent limits, slow logs and status pages. FPM is the modern default.

    Key Points

    • mod_php: embedded, prefork only
    • FPM: separate pools, better resource control
    • Nginx + FPM is standard

    Permalink

  26. What are `random_bytes()` and `random_int()`, and why were they important?
  27. What important features were removed in PHP 7.0?
  28. What is libsodium in PHP 7.2 and why does it matter?
  29. What is `JSON_THROW_ON_ERROR` (PHP 7.3)?
  30. What variance support arrived in PHP 7.4?
  31. Which PHP 7.4 deprecations commonly affect legacy code?
  32. PHP 7.4 reached end of life in November 2022. What does that mean for teams still running it?
  33. How do you safely refactor a large legacy PHP 7 codebase without tests?
  34. What do `abstract` and `final` mean for classes and methods?
  35. How do you convert PHP warnings and notices into exceptions?
  36. How did PHPUnit evolve across PHP 7 versions, and how do you write a basic test?
  37. Explain `array_map`, `array_filter` and `array_reduce` with examples.
  38. How do you call a REST API from PHP 7 using cURL?
  39. How would you implement JWT authentication in a PHP 7 API?
  40. Describe a step-by-step strategy for upgrading a production app from PHP 7.2 to 7.4 and then to 8.x.
  41. Why did PHP skip version 6?
  42. What are anonymous classes in PHP 7?
  43. What is group use declaration syntax?
  44. What did PHP 7 add to generators?
  45. What does `intdiv()` do and why was it added?
  46. What are `Closure::call()` (7.0) and `Closure::fromCallable()` (7.1)?
  47. What is Uniform Variable Syntax in PHP 7 and why did it break some code?
  48. What did PHP 7 change about constants?
  49. What is the Unicode codepoint escape syntax in PHP 7?
  50. What did PHP 7 add to `unserialize()` for security?
  51. How did assertions change in PHP 7 (expectations)?
  52. How did `foreach` behavior change in PHP 7?
  53. What is the `iterable` pseudo-type?
  54. How did array destructuring improve in PHP 7.1?
  55. What did `pcntl_async_signals()` change in PHP 7.1?
  56. What did PHP 7.2 add to the type system?
  57. What changed with `count()` on non-countable values in PHP 7.2?
  58. What did PHP 7.3 change about heredoc and nowdoc?
  59. Which useful array functions were added in PHP 7.3?
  60. Where are trailing commas allowed, and in which versions?
  61. How did PHP 7.3 improve cookie security options?
  62. What else changed in PHP 7.3?
  63. What small syntax features did PHP 7.4 add?
  64. What is FFI in PHP 7.4?
  65. What are `__serialize()` and `__unserialize()` (PHP 7.4)?
  66. What is `WeakReference` (PHP 7.4)?
  67. Explain variable scope in PHP: local, global and static variables.
  68. What is the difference between static and instance members?
  69. Explain `__get`, `__set`, `__isset`, `__unset` and `__call`.
  70. Which PHP 5.x features remain central in PHP 7 code?
  71. What causes the 'headers already sent' error and how do you fix it?
  72. How do you read large files efficiently in PHP?
  73. What are common date/time pitfalls in PHP?
  74. Explain PHP's sort functions: `sort`, `asort`, `ksort`, `usort`, `uasort`, `uksort`.
  75. Which string functions are most commonly used and what are their pitfalls?
  76. How should a PHP 7 app render HTML templates safely?
  77. Which Laravel and Symfony versions ran on PHP 7, and why does it matter for upgrades?
  78. What legacy PHP security features (like register_globals and magic quotes) should you recognize in old code?
  79. How would you optimize a PHP 7 application without upgrading PHP?
  80. Compare `var_dump()`, `print_r()` and `var_export()`.
  81. How do you use `preg_match`, `preg_replace` and `preg_replace_callback`?
  82. How do you handle CORS in a plain PHP API?
  83. How should configuration and secrets be managed in a PHP 7 application?
  84. What is APCu and when would you use it versus Redis?
  85. What are the Singleton and Factory patterns, and why is Singleton often considered an anti-pattern?
  86. What is the Reflection API used for?
  87. How do you debug PHP applications effectively?
  88. How do you run scheduled tasks for a PHP app?
  89. Give an example of polymorphism with interfaces in PHP 7.
  90. What do `__toString()` and `__invoke()` do?
  91. How do you make a custom object iterable with `foreach`?
  92. Which HTTP security headers should a PHP application send?
  93. How do you validate and sanitize input in PHP 7?
  94. How do you send email reliably from PHP 7?
  95. Which OPcache and realpath settings matter for PHP 7 performance?
  96. How did zval and array internals change in PHP 7 to improve performance?
  97. How do you pin a project to work on PHP 7 while preparing for PHP 8 with Composer?
  98. How can generators be used as simple coroutines (`send()`)?
  99. What are negative string offsets in PHP 7.1?