PHP 7.0: Major Features
PHP 7.0 is the generational reset after PHP 5: scalar type declarations (coercive by default, strict_types optional), return types, the null coalescing (??) and spaceship (<=>) operators, anonymous classes, Closure::call(), generator return values and yield from, intdiv(), random_bytes() / random_int(), filtered unserialize(), and preg_replace_callback_array(). Under the hood, many former fatals become Error exceptions under the new Throwable hierarchy—your global error and exception handlers must understand Error, not only Exception.
Table of Contents
- Scalar types &
strict_types - Return types
- Null coalescing (
??) - Spaceship operator (
<=>) - Anonymous classes
Closure::call()- Generators:
yield from& return values intdiv(), CSPRNG,unserializeoptions- Group
useimports - Practical recipes
- Backward incompatible changes (high level)
- Removed extensions & SAPIs
- Deprecations
- Other migration notes
Scalar types & strict_types
Parameters may declare string, int, float, bool in addition to class/array/callable hints. Without declare(strict_types=1);, PHP uses coercive typing (e.g. "123" → int). With strict types, mismatches throw TypeError.
declare(strict_types=1);
function increment(int $x): int {
return $x + 1;
}
Return types
Functions and methods can declare return types; TypeError fires when the returned value does not satisfy the declaration (including void’s absence in 7.1+—on 7.0 focus on value returns).
Null coalescing (??)
$name = $_GET['name'] ?? 'guest';
Does not emit notices for undefined indices—unlike isset(...) ? ... : ... chains it is concise and safe for arrays.
Spaceship operator (<=>)
Three-way comparison returning -1 / 0 / 1—ideal for usort comparators.
usort($rows, function ($a, $b) {
return $a['score'] <=> $b['score'];
});
Anonymous classes
$logger = new class implements LoggerInterface {
public function log($level, $message, array $context = []) { /* ... */ }
};
Closure::call()
Bind and invoke in one step:
$getter = function () { return $this->value; };
$getter->call($object);
Generators: yield from & return values
yield fromdelegates iteration to another generator/iterable.return $final;inside a generator exposesGenerator::getReturn()after completion.
intdiv(), CSPRNG, unserialize options
intdiv($a, $b)for integer division throwingArithmeticErroron/0.random_bytes()/random_int()for cross-platform CSPRNG (prefer overmt_rand()for secrets).unserialize($data, ['allowed_classes' => [...]])to block unexpected object hydration.
Group use imports
use Foo\Bar\{Baz, Qux};
Practical recipes
Safe input defaults
$limit = (int) ($_GET['limit'] ?? 25);
Comparator sort
usort($items, function ($a, $b) {
return strcmp($a['id'], $b['id']);
});
Backward incompatible changes (high level)
This release is large—treat migration70 incompatible as the source of truth. Highlights that hit legacy codebases:
Errors & exceptions
Throwablebase; many fatals →Error/TypeError/ParseError.set_exception_handler: typing the parameter asExceptionfatals whenErroris thrown—useThrowable(or untyped) on PHP 7+.
Parser & variables
- Indirect variable/property/method access is evaluated strictly left-to-right—expressions like
$$foo['bar']['baz']need explicit{}to keep PHP 5 meaning. list()assignment order is definition order (not reversed); emptylist()is illegal;list()cannot unpack strings (usestr_split()).
Arrays, foreach, functions
- Array ordering for elements created via reference assignments differs from PHP 5.
foreachno longer moves the internal array pointer; by-valueforeachworks on a copy; by-reference iteration tracks appends more predictably.- Redundant parentheses no longer suppress “only variables should be passed by reference” notices.
Strings & integers
- Hex strings (
"0xFF") are not auto-treated as numbers in numeric contexts. $inside double-quoted strings with complex${}forms changed—audit generated templates.
Unicode & output
substr()and related functions stay byte-based—combine withmb_*for UTF-8 text.
Many extension-specific BC items (MySQL removal, ereg removal, etc.) are listed under removed below.
Removed extensions & SAPIs
PHP 7 drops classic PHP 4/5-era extensions and SAPIs—including mysql, ereg*, mssql, sybase_ct, mcrypt (still present in 7.0 but deprecated later), old SAPIs (apache2filter, …)—see migration70 removed. Replace mysql_* with mysqli or PDO, and ereg_* with preg_*.
Deprecations
PHP 4-style class-name constructors, static calls to non-static methods, password_hash() custom salt option, ldap_sort(), capture_session_meta SSL context, and more—see migration70 deprecated.
Other migration notes
assert()supports an expectations API withzend.assertionsINI—string assertions remain a migration footgun (deprecated in later 7.x).- Review removed INI directives, changed
json_decode()/json_encode()error behavior, andsplit()removal (usepreg_split()/explode()).
Closing thoughts
Upgrading 5.x → 7.0 is a project, not a patch: run static analysis, fix mysql/ereg, add catch (Throwable $e) around framework front controllers, and rehearse list()/foreach edge cases. Once stable on 7.0, 7.1+ minors are comparatively incremental—nullable types, then count() warnings in 7.2, then heredoc/JSON exceptions in 7.3.