Backward incompatible changes

Prevent number_format from returning negative zero

Previously, it was possible for the number_format function to return -0. Whilst this is perfectly valid according to the IEEE 754 floating point specification, this oddity was not desirable for displaying formatted numbers in a human-readable form.

<?php

var_dump(number_format(-0.01)); // now outputs string(1) "0" instead of string(2) "-0"

Convert numeric keys in object and array casts

Numeric keys are now better handled when casting arrays to objects and objects to arrays (either from explicit casting or by settype).

This means that integer (or stringy integer) keys from arrays being casted to objects are now accessible:

<?php

// array to object
$arr = [0 => 1];
$obj = (object) $arr;
var_dump(
    $obj,
    $obj->{'0'}, // now accessible
    $obj->{0} // now accessible
);

The above example will output:

object(stdClass)#1 (1) {
  ["0"]=>    // string key now, rather than integer key
  int(1)
}
int(1)
int(1)

And integer (or stringy integer) keys from objects being casted to arrays are now accessible:

<?php

// object to array
$obj = new class {
    public function __construct()
    {
        $this->{0} = 1;
    }
};
$arr = (array) $obj;
var_dump(
    $arr,
    $arr[0], // now accessible
    $arr['0'] // now accessible
);

The above example will output:

array(1) {
  [0]=>    // integer key now, rather than string key
  int(1)
}
int(1)
int(1)

Disallow passing null to get_class

Previously, passing null to the get_class function would output the name of the enclosing class. This behaviour has now been removed, where an E_WARNING will be output instead. To achieve the same behaviour as before, the argument should simply be omitted.

Warn when counting non-countable types

An E_WARNING will now be emitted when attempting to count non-countable types (this includes the sizeof alias function).

<?php

var_dump(
    count(null), // NULL is not countable
    count(1), // integers are not countable
    count('abc'), // strings are not countable
    count(new stdClass), // objects not implementing the Countable interface are not countable
    count([1,2]) // arrays are countable
);

The above example will output:

Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d

Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d

Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d

Warning: count(): Parameter must be an array or an object that implements Countable in %s on line %d
int(0)
int(1)
int(1)
int(1)
int(2)

Move ext/hash from resources to objects

As part of the long-term migration away from resources, the Hash extension has been updated to use objects instead of resources. The change should be seamless for PHP developers, except for where is_resource checks have been made (which will need updating to is_object instead).

Improve SSL/TLS defaults

The following changes to the defaults have been made:

  • tls:// now defaults to TLSv1.0 or TLSv1.1 or TLSv1.2
  • ssl:// an alias of tls://
  • STREAM_CRYPTO_METHOD_TLS_* constants default to TLSv1.0 or TLSv1.1 + TLSv1.2, instead of TLSv1.0 only

gettype return value on closed resources

Previously, using gettype on a closed resource would return a string of "unknown type". Now, a string of "resource (closed)" will be returned.

is_object and __PHP_Incomplete_Class

Previously, using is_object on the __PHP_Incomplete_Class class would return false. Now, true will be returned.

Promote the error level of undefined constants

Unqualified references to undefined constants will now generate an E_WARNING (instead of an E_NOTICE). In the next major version of PHP, they will generate Error exceptions.

Windows support

The officially supported, minimum Windows versions are now Windows 7/Server 2008 R2.

Checks on default property values of traits

Compatibility checks upon default trait property values will no longer perform casting.

object for class names

The object name was previously soft-reserved in PHP 7.0. This is now hard-reserved, prohibiting it from being used as a class, trait, or interface name.

NetWare support

Support for NetWare has now been removed.

array_unique with SORT_STRING

While array_unique with SORT_STRING formerly copied the array and removed non-unique elements (without packing the array afterwards), now a new array is built by adding the unique elements. This can result in different numeric indexes.

bcmod changes with floats

The bcmod function no longer truncates fractional numbers to integers. As such, its behavior now follows fmod, rather than the % operator. For example bcmod('4', '3.5') now returns 0.5 instead of 1.

Hashing functions and non-cryptographic hashes

The hash_hmac, hash_hmac_file, hash_pbkdf2, and hash_init (with HASH_HMAC) functions no longer accept non-cryptographic hashes.

json_decode function options

The json_decode function option, JSON_OBJECT_AS_ARRAY, is now used if the second parameter (assoc) is null. Previously, JSON_OBJECT_AS_ARRAY was always ignored.

rand and mt_rand output

Sequences generated by rand and mt_rand for a specific seed may differ from PHP 7.1 on 64-bit machines (due to the fixing of a modulo bias bug in the implementation).

Removal of sql.safe_mode ini setting

The sql.safe_mode ini setting has now been removed.

Changes to date_parse and date_parse_from_format

The zone element of the array returned by date_parse and date_parse_from_format represents seconds instead of minutes now, and its sign is inverted. For instance -120 is now 7200.

Incoming Cookies

As of PHP 7.2.34, the names of incoming cookies are no longer url-decoded for security reasons.