never Return Type (PHP 8.1)
debt(d5/e1/b1/t5)
Closest to 'specialist tool catches' (d5). PHPStan and Psalm (listed in detection_hints.tools) can detect functions that always throw or exit but lack the never return type, enabling unreachable code detection. These are specialist static analysis tools, not default linters or compiler errors.
Closest to 'one-line patch' (e1). The quick_fix states simply adding 'never' as the return type declaration — this is a single-line change to the function signature with no refactoring required.
Closest to 'minimal commitment' (b1). The never return type is a per-function declaration with no architectural reach. It applies to individual helper functions (redirect helpers, abort functions) and doesn't impose any ongoing maintenance tax on the codebase.
Closest to 'notable trap' (t5). The misconception explicitly states developers confuse never with void — a documented gotcha. void means 'returns without a value' while never means 'never returns at all'. This is a meaningful distinction that most PHP developers eventually learn, but it's not immediately obvious from the names alone.
Also Known As
TL;DR
Explanation
The never return type (PHP 8.1) declares that a function will never return normally — it always throws an exception, calls exit(), or enters an infinite loop. This is stricter than void (which returns, just without a value). Static analysers use never to mark code after a call as unreachable and to verify that all branches of a conditional throw rather than fall through. Practical uses: exception factory helpers (throw new InvalidArgumentException(...) extracted into a method), router 404 handlers that always abort(), and test assertion helpers that always throw on failure. A function declared never that actually returns causes a TypeError at runtime.
Common Misconception
Why It Matters
Common Mistakes
- Not using never on redirect-and-exit helpers — analysers cannot tell that code after the call is unreachable.
- Using void instead of never — void means the function returns without a value; never means it doesn't return at all.
- Declaring never on a function that can sometimes return normally — this is a type error PHP will enforce.
- Not understanding that never makes the function a dead end in control flow — useful for abort, throw helpers.
Code Examples
// Without 'never' — analyser doesn't know redirect() exits:
function redirect(string $url): void { // Should be: never
header('Location: ' . $url);
exit();
}
redirect('/login');
$user = getCurrentUser(); // Analyser flags this as reachable — false positive
// With 'never', analyser correctly marks this as unreachable
function abort(int $code): never {
http_response_code($code);
exit();
}
function fail(string $msg): never {
throw new RuntimeException($msg);
}