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.
-
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 theThrowableerror 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 catchableErrorexceptions. The oldmysql_*extension anderegfunctions were removed.Key Points
- ~2x throughput, lower memory (PHPNG)
- Scalar and return types,
strict_types ??,<=>, anonymous classes- Fatal errors become
Errorexceptions - Removed
mysql_*,ereg, ASP tags
-
Most asked Explain scalar type declarations and coercive vs strict mode in PHP 7.
Summary
PHP 7 allows
int,float,stringandboolparameter types. By default (coercive mode) compatible values are converted, e.g.'5'→5; withdeclare(strict_types=1)mismatches throwTypeError.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 anintmay be passed to afloatparameter.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 modeKey Points
- Types: int, float, string, bool
- Coercive by default
strict_types=1per file, caller-decided- Only int → float widening allowed in strict mode
-
Most asked How do return type declarations work in PHP 7?
Summary
You can append
: typeto a function to declare what it returns; PHP checks (and in coercive mode converts) the returned value, throwingTypeErroron mismatch.Longer Answer
PHP 7.0 allowed scalar, array, callable, class and
selfreturn types. PHP 7.1 added nullable (?string) andvoid, and 7.2 addedobject. A method overriding a parent must keep a compatible return type (covariance only fully arrived in 7.4).Key Points
function f(): int?Tnullable andvoidin 7.1objectin 7.2- Full covariance in 7.4
-
Most asked What does the null coalescing operator `??` do, and how is it different from `isset()` with a ternary?
Summary
$a ?? $breturns$aif it exists and isn't null, otherwise$b, without emitting notices. It's shorthand forisset($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 treat0,''orfalseas missing.Code Example
<?php $page = $_GET['page'] ?? 1; $host = $config['db']['host'] ?? getenv('DB_HOST') ?? 'localhost'; $options['timeout'] ??= 30; // PHP 7.4Key Points
- Equivalent to
isset($x) ? $x : $default - No undefined index notices
- Chainable
??=(7.4) assigns if null
- Equivalent to
-
Most asked Explain the `Throwable`, `Error` and `Exception` hierarchy introduced in PHP 7.
Summary
PHP 7 made most fatal errors catchable by throwing
Errorobjects. BothErrorandExceptionimplement the newThrowableinterface, butErrordoes not extendException.Longer Answer
Subclasses of
ErrorincludeTypeError,ParseError,ArithmeticError,DivisionByZeroErrorandArgumentCountError(7.1). Oldcatch (Exception $e)blocks don't catch them, which is intentional to preserve BC. CatchThrowableat top-level handlers. User classes can't implementThrowabledirectly; extendExceptioninstead.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,Exceptioncatch (Exception)doesn't catchError- Catch
Throwablein global handlers set_exception_handlerreceivesThrowablein 7+
-
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 ornull, for parameters and return types.Longer Answer
Before 7.1 the only way to accept null was a
= nulldefault, which also made the parameter optional.?string $nameis required but may be null. (Implicit nullability via= nulldefaults 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
?Tmeans T or null- Different from an optional parameter
- Works for params and return types
- Typed properties (7.4) also support
?T
-
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 anErrorwhen 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= nulldefault if you want null initially. All types exceptvoidandcallableare supported, andstrict_typesaffects 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 initializationKey Points
private ?string $name = null;- Uninitialized ≠ null
- No
voidorcallableproperty types - Writes are type-checked
-
Most asked What are arrow functions in PHP 7.4 and how do they differ from closures?
Summary
Arrow functions
fn($x) => exprare single-expression closures that automatically capture outer variables by value, with nouseclause needed.Longer Answer
They're ideal for short callbacks in
array_map,array_filterandusort. Limitations: one expression only (no statements), and captured variables are by value, so they can't modify outer variables. They also auto-bind$thisin class context (usestatic fnto 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
-
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:
matchandmixedbecame 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.
Resourcehandles turned into objects for curl, GD, sockets, XML and more, sois_resource()checks break.create_function(),each()andmoney_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
-
Most asked What does the spaceship operator `<=>` return and where is it used?
Summary
$a <=> $breturns -1, 0 or 1 when$ais less than, equal to, or greater than$b, which makes it ideal forusortcomparators.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; }); // descendingKey Points
- Returns -1, 0, or 1
- Perfect for
usort/uasortcallbacks - Compare arrays for multi-column sorting
-
Most asked What does the `void` return type mean?
Summary
void(PHP 7.1) declares a function returns nothing; it may use a barereturn;but notreturn 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
nullto the caller.voidcannot be nullable or part of a union.Key Points
- Bare
return;allowed, no value return null;is a compile error- Caller receives null
- Bare
-
Most asked What is multi-catch exception handling in PHP 7.1?
Summary
A single
catchblock 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
instanceofif 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
-
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 viaERRMODE_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 -
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) and0 == 'abc'is true. This enables authentication bypasses with 'magic hashes'. Always use===andhash_equals().Longer Answer
Classic bug:
if (md5($input) == $storedHash), where both hashes start with0efollowed by digits, so they compare equal as floats (0). Alsoin_array,array_searchandswitchuse loose comparison by default. Use strict comparison, strict flags and timing-safehash_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
-
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' == 1is true but'1' === 1is 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
-
Most asked Explain `public`, `protected` and `private` visibility in PHP.
Summary
publicmembers are accessible everywhere,protectedmembers within the class and its subclasses, andprivatemembers 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+finalclasses reduce the API surface you must maintain.Key Points
- Public → anywhere
- Protected → class hierarchy
- Private → declaring class only
- Class-based, not instance-based
-
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
insteadofandas.Key Points
- Compile-time copy-paste into classes
- Not a type, so can't type-hint
- Can declare abstract methods to require host members
-
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
__autoloaddeprecated 7.2, removed 8.0
-
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()andempty()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; usearray_key_exists()to distinguish.Key Points
isset: exists and not nullempty: missing or falsy ('0', 0, '', [], null, false)is_null: strictly nullarray_key_existsfor null-valued keys
Comparison / Tradeoffs
Value isset empty is_null null false true true '' true true false '0' true true false [] true true false -
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
-
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;
clonecreates 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
cloneis shallow__clone()for deep copies- Immutability sidesteps aliasing
-
Most asked How do PHP sessions work under the hood?
Summary
session_start()reads a session ID from a cookie (defaultPHPSESSID), 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 withuse_strict_mode,cookie_secure,cookie_httponlyandcookie_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
-
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 + $defaultsfor defaultsarray_replaceoverwrites by key
-
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
-
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
- What are `random_bytes()` and `random_int()`, and why were they important?
- What important features were removed in PHP 7.0?
- What is libsodium in PHP 7.2 and why does it matter?
- What is `JSON_THROW_ON_ERROR` (PHP 7.3)?
- What variance support arrived in PHP 7.4?
- Which PHP 7.4 deprecations commonly affect legacy code?
- PHP 7.4 reached end of life in November 2022. What does that mean for teams still running it?
- How do you safely refactor a large legacy PHP 7 codebase without tests?
- What do `abstract` and `final` mean for classes and methods?
- How do you convert PHP warnings and notices into exceptions?
- How did PHPUnit evolve across PHP 7 versions, and how do you write a basic test?
- Explain `array_map`, `array_filter` and `array_reduce` with examples.
- How do you call a REST API from PHP 7 using cURL?
- How would you implement JWT authentication in a PHP 7 API?
- Describe a step-by-step strategy for upgrading a production app from PHP 7.2 to 7.4 and then to 8.x.
- Why did PHP skip version 6?
- What are anonymous classes in PHP 7?
- What is group use declaration syntax?
- What did PHP 7 add to generators?
- What does `intdiv()` do and why was it added?
- What are `Closure::call()` (7.0) and `Closure::fromCallable()` (7.1)?
- What is Uniform Variable Syntax in PHP 7 and why did it break some code?
- What did PHP 7 change about constants?
- What is the Unicode codepoint escape syntax in PHP 7?
- What did PHP 7 add to `unserialize()` for security?
- How did assertions change in PHP 7 (expectations)?
- How did `foreach` behavior change in PHP 7?
- What is the `iterable` pseudo-type?
- How did array destructuring improve in PHP 7.1?
- What did `pcntl_async_signals()` change in PHP 7.1?
- What did PHP 7.2 add to the type system?
- What changed with `count()` on non-countable values in PHP 7.2?
- What did PHP 7.3 change about heredoc and nowdoc?
- Which useful array functions were added in PHP 7.3?
- Where are trailing commas allowed, and in which versions?
- How did PHP 7.3 improve cookie security options?
- What else changed in PHP 7.3?
- What small syntax features did PHP 7.4 add?
- What is FFI in PHP 7.4?
- What are `__serialize()` and `__unserialize()` (PHP 7.4)?
- What is `WeakReference` (PHP 7.4)?
- Explain variable scope in PHP: local, global and static variables.
- What is the difference between static and instance members?
- Explain `__get`, `__set`, `__isset`, `__unset` and `__call`.
- Which PHP 5.x features remain central in PHP 7 code?
- What causes the 'headers already sent' error and how do you fix it?
- How do you read large files efficiently in PHP?
- What are common date/time pitfalls in PHP?
- Explain PHP's sort functions: `sort`, `asort`, `ksort`, `usort`, `uasort`, `uksort`.
- Which string functions are most commonly used and what are their pitfalls?
- How should a PHP 7 app render HTML templates safely?
- Which Laravel and Symfony versions ran on PHP 7, and why does it matter for upgrades?
- What legacy PHP security features (like register_globals and magic quotes) should you recognize in old code?
- How would you optimize a PHP 7 application without upgrading PHP?
- Compare `var_dump()`, `print_r()` and `var_export()`.
- How do you use `preg_match`, `preg_replace` and `preg_replace_callback`?
- How do you handle CORS in a plain PHP API?
- How should configuration and secrets be managed in a PHP 7 application?
- What is APCu and when would you use it versus Redis?
- What are the Singleton and Factory patterns, and why is Singleton often considered an anti-pattern?
- What is the Reflection API used for?
- How do you debug PHP applications effectively?
- How do you run scheduled tasks for a PHP app?
- Give an example of polymorphism with interfaces in PHP 7.
- What do `__toString()` and `__invoke()` do?
- How do you make a custom object iterable with `foreach`?
- Which HTTP security headers should a PHP application send?
- How do you validate and sanitize input in PHP 7?
- How do you send email reliably from PHP 7?
- Which OPcache and realpath settings matter for PHP 7 performance?
- How did zval and array internals change in PHP 7 to improve performance?
- How do you pin a project to work on PHP 7 while preparing for PHP 8 with Composer?
- How can generators be used as simple coroutines (`send()`)?
- What are negative string offsets in PHP 7.1?