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

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 from delegates iteration to another generator/iterable.
  • return $final; inside a generator exposes Generator::getReturn() after completion.

intdiv(), CSPRNG, unserialize options

  • intdiv($a, $b) for integer division throwing ArithmeticError on /0.
  • random_bytes() / random_int() for cross-platform CSPRNG (prefer over mt_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

  • Throwable base; many fatals → Error / TypeError / ParseError.
  • set_exception_handler: typing the parameter as Exception fatals when Error is thrown—use Throwable (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); empty list() is illegal; list() cannot unpack strings (use str_split()).

Arrays, foreach, functions

  • Array ordering for elements created via reference assignments differs from PHP 5.
  • foreach no longer moves the internal array pointer; by-value foreach works 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 with mb_* 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 with zend.assertions INI—string assertions remain a migration footgun (deprecated in later 7.x).
  • Review removed INI directives, changed json_decode()/json_encode() error behavior, and split() removal (use preg_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.