PHP 7.1: Major Features
PHP 7.1 makes typed PHP practical day-to-day: nullable types (?T), void returns, the iterable pseudo-type, visibility on class constants, list() with keys, multi-catch, and async-style quality-of-life improvements (e.g. Closure::fromCallable()). It also tightens runtime edges—most famously ArgumentCountError when user-defined functions are called with too few arguments—and changes subtle behavior around strings, DateTime, unserialize() options, and sorting stability. Plan migrations around: argument arity, session INI removals, and any code that treated strings like arrays with [].
Table of Contents
- Nullable types (
?T) voidreturn typeiterabletype- Class constant visibility
list()with keys & symmetric destructuring- Multi-catch
- Notable additions
- Practical recipes
- Backward incompatible changes
- Deprecations
- Other changes
Nullable types (?T)
Parameters and return types may be ?Foo—accepting Foo or null. You still must return a value (or null) on all paths; bare return; is invalid unless the return type is void.
function findUser(?int $id): ?User {
return $id === null ? null : User::load($id);
}
void return type
Functions that do not return a usable value can declare void. return; is allowed; return $value; is not.
iterable type
iterable accepts arrays or any object implementing Traversable—a single type for “foreach-able” inputs.
Class constant visibility
Constants support public / protected / private visibility like properties.
list() with keys & symmetric destructuring
list() can target specific keys (list(0 => $a, 1 => $b) = ... style patterns per manual), and the short [$a, $b] = $arr destructuring syntax arrives—use it to clarify tuple unpacking.
Multi-catch
try {
// ...
} catch (FooException | BarException $e) {
// shared handler
}
Notable additions
Closure::fromCallable()for wrapping callables with a realClosureinstance.void/?Typeinterplay documented strictly by the engine.pcntl_async_signals()andcurl_multi_errno()/curl_share_errno()(see migration71 new features for the full list).
Practical recipes
Avoid too-few-argument calls
function save(User $user, bool $flush = false): void { /* ... */ }
// Always pass required args explicitly; optional params must truly be optional.
Nullable + early return
function label(?string $s): string {
return $s ?? 'default';
}
Backward incompatible changes
User-defined arity
- Calling a user-defined function with too few arguments now throws
ArgumentCountError(previously: warning). Internal functions largely keep old behavior—audit wrappers that relied on warnings.
Session INI removed
session.entropy_file,session.entropy_length,session.hash_function,session.hash_bits_per_characterare gone—modern session IDs no longer use that hashing pipeline (see RFC on session ID generation).
Arrays, references, sorting
- Auto-vivified array elements via reference assignment may appear in a different order than PHP 7.0 (and align closer to PHP 5 behavior in common patterns—verify if you depended on 7.0 ordering).
- Sorts may reorder equal-comparing elements differently—never rely on stability of ties.
Strings vs arrays
- The empty
[]append on strings ($s[] = 'x'with$sas string) and related “string as array” patterns are rejected—strings are not autovivified into arrays anymore. Assigning into numeric offsets on strings now follows byte-offset string semantics (see manual examples).
Serialization & time
unserialize($data, $options):allowed_classesmust be bool or array—other typesfalse+ warning.DateTime/DateTimeImmutableconstructed from “now” include microseconds—naive equality of two “just created” instances often fails.
JSON, mbstring, TLS
- With
JSON_UNESCAPED_UNICODE,U+2028/U+2029are escaped. mb_ereg()/mb_eregi()third arg is set to empty array when no match.sslv2stream removed from OpenSSL.
Lexical closures
usevariables cannot reuse superglobal names,$this, or parameter names.
Wide “fatal → Error” sweep
Many extensions now throw Error instead of fatals for invalid internal states—see migration71 incompatible for the long per-extension list (DOM, Intl, mysqli, Session handlers, SimpleXML, SPL, Zip, …).
Deprecations
- ext/mcrypt is deprecated (removed from core in PHP 7.2—plan OpenSSL/Sodium).
emodifier formb_ereg_replace()/mb_eregi_replace()deprecated (eval-style replacement).
Other changes
- Invalid numeric string arithmetic now emits warnings/notices where silent coercion happened before.
- Octal escape overflows in strings warn.
Closing thoughts
Treat PHP 7.1 as “typed PHP v1”: nullable/void/iterable unlock safer APIs, but ArgumentCountError and string offset changes will surface latent bugs from PHP 5-era code. Fix arity and string handling before chasing 7.2’s count() warnings.