下位互換性のない変更点

関数に渡す引数が少ない場合の挙動

これまでのバージョンでは、ユーザー定義の関数に渡す引数が足りない場合は warning が発生していました。PHP 7.1 以降では、warning ではなく Error 例外が発生するようになります。 この変更はユーザー定義の関数に対してだけのもので、 内部関数には影響を及ぼしません。

<?php
function test($param){}
test();

上の例の出力は、 たとえば以下のようになります。

Fatal error: Uncaught ArgumentCountError: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

スコープを調べる関数の動的呼び出しの禁止

ある種の関数について、動的な呼び出し ($func()array_map('extract', ...) のような形式) が使えなくなりました。対象になるのは、別のスコープを調べたり変更したり、 あいまいな挙動になってしまったりするような関数です。 この変更の影響を受ける関数は、以下のとおりです。

<?php
(function () {
    
$func 'func_num_args';
    
$func();
})();

上の例の出力は以下となります。

Warning: Cannot call func_num_args() dynamically in %s on line %d

クラス、インターフェイス、トレイトに使えない名前

これらのキーワードが、クラスやインターフェイスやトレイトの名前として使えなくなりました。

数値形式文字列の変換が科学記法に対応

数値形式の文字列の演算や型変換が、科学記法に対応するようになりました。 (int) によるキャストや、 intval() (基数が10の場合)、 settype()decbin()decoct()dechex() といった関数もその対象です。

mt_rand() のアルゴリズムの修正

mt_rand() のデフォルトが、修正版のメルセンヌ・ツイスタ アルゴリズムを使うようになりました。mt_srand() の結果に依存するコードを書いていた場合は、mt_srand() のオプションの第二引数に MT_RAND_PHP を指定すると、これまでの挙動 (間違った実装) を維持できます。

rand()srand() が、 それぞれ mt_rand()mt_srand() のエイリアスとなる

rand()srand() は、それぞれ mt_rand()mt_srand() のエイリアスになりました。つまり、 rand()shuffle()str_shuffle()array_rand() の出力がこれまでのバージョンとは変わるということです。

ASCII 制御文字 delete は識別子として使えない

ASCII 制御文字 delete (0x7F) は、 クォートしない限りは識別子として使えなくなりました。

error_logsyslog を指定した場合の変更

INI 項目 error_log の設定値を syslog にした場合に、PHP のエラーレベルが syslog のエラーレベルにマッピングされるようになりました。 これまでのバージョンではすべてのエラーが notice レベルで記録されていましたが、 この変更によって、今までよりも細やかな区別ができるようになります。

未完成のオブジェクトのデストラクタは呼び出されない

オブジェクトのコンストラクタの実行中に例外がスローされた場合に、 そのオブジェクトのデストラクタが呼ばれることはなくなりました。 以前のバージョンでは、場合によっては (例: そのオブジェクトが例外バックトレースなどで外部から参照される場合) デストラクタが呼ばれることもありました。

参照渡しの引数の call_user_func() での扱い

引数を参照渡しで受け取る関数を call_user_func() から呼んだときに、例外が発生するようになりました。 以前のバージョンでは、完全修飾形式の呼び出しであるか否かによってこの場合の挙動が異なっていました。

さらにこの場合、call_user_func()call_user_func_array() は関数呼び出しを中断しなくなりました。 "expected reference" という警告は出すものの、処理自体はそのまま続行します。

文字列における空のインデックス演算子はサポートしない

文字列に空のインデックス演算子を適用する (例: $str[] = $x) と、fatal エラーが発生します。これまでのバージョンではエラーにならず、 ただ配列に変換されるだけでした。

Assignment via string index access on an empty string

String modification by character on an empty string now works like for non-empty strings, i.e. writing to an out of range offset pads the string with spaces, where non-integer types are converted to integer, and only the first character of the assigned string is used. Formerly, empty strings where silently treated like an empty array.

<?php
$a 
'';
$a[10] = 'foo';
var_dump($a);
?>

上の例の PHP 7.0 での出力は、このようになります。

array(1) {
  [10]=>
  string(3) "foo"
}

上の例の PHP 7.1 での出力は、このようになります。

string(11) "          f"

削除された INI 項目

以下の INI 項目は、削除されました。

  • session.entropy_file
  • session.entropy_length
  • session.hash_function
  • session.hash_bits_per_character

参照による代入で自動的に作られる配列の要素の並び順の変更

参照による代入で配列の要素が自動的に作られる場合に、その並び順が変更されました。

<?php
$array 
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>

上の例の PHP 7.0 での出力は、このようになります。

array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}

上の例の PHP 7.1 での出力は、このようになります。

array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

同値な要素の並び順

内部的なソートアルゴリズムが改良されたことに伴って、 比較したときに等しいとみなされる要素の並び順が以前とは変わるかもしれません。

注意:

同値な要素の並び順に依存するコードは書かないようにしましょう。 その並び順がいつまでも同じであるとは限りません。

Error message for E_RECOVERABLE errors

The error message for E_RECOVERABLE errors has been changed from "Catchable fatal error" to "Recoverable fatal error".

$options parameter of unserialize()

The allowed_classes element of the $options parameter of unserialize() is now strictly typed, i.e. if anything other than an array or a boolean is given, unserialize() returns FALSE and issues an E_WARNING.

DateTime constructor incorporates microseconds

DateTime and DateTimeImmutable now properly incorporate microseconds when constructed from the current time, either explicitly or with a relative string (e.g. "first day of next month"). This means that naive comparisons of two newly created instances will now more likely return FALSE instead of TRUE:

<?php
new DateTime() == new DateTime();
?>

Fatal errors to Error exceptions conversions

In the Date extension, invalid serialization data for DateTime or DatePeriod classes, or timezone initialization failure from serialized data, will now throw an Error exception from the __wakeup() or __set_state() methods, instead of resulting in a fatal error.

In the DBA extension, data modification functions (such as dba_insert()) will now throw an Error exception instead of triggering a catchable fatal error if the key does not contain exactly two elements.

In the DOM extension, invalid schema or RelaxNG validation contexts will now throw an Error exception instead of resulting in a fatal error. Similarly, attempting to register a node class that does not extend the appropriate base class, or attempting to read an invalid property or write to a readonly property, will also now throw an Error exception.

In the IMAP extension, email addresses longer than 16385 bytes will throw an Error exception instead of resulting in a fatal error.

In the Intl extension, failing to call the parent constructor in a class extending Collator before invoking the parent methods will now throw an Error instead of resulting in a recoverable fatal error. Also, cloning a Transliterator object will now throw an Error exception on failure to clone the internal transliterator instead of resulting in a fatal error.

In the LDAP extension, providing an unknown modification type to ldap_batch_modify() will now throw an Error exception instead of resulting in a fatal error.

In the mbstring extension, the mb_ereg() and mb_eregi() functions will now throw a ParseError exception if an invalid PHP expression is provided and the 'e' option is used.

In the Mcrypt extension, the mcrypt_encrypt() and mcrypt_decrypt() will now throw an Error exception instead of resulting in a fatal error if mcrypt cannot be initialized.

In the mysqli extension, attempting to read an invalid property or write to a readonly property will now throw an Error exception instead of resulting in a fatal error.

In the Reflection extension, failing to retrieve a reflection object or retrieve an object property will now throw an Error exception instead of resulting in a fatal error.

In the Session extension, custom session handlers that do not return strings for session IDs will now throw an Error exception instead of resulting in a fatal error when a function is called that must generate a session ID.

In the SimpleXML extension, creating an unnamed or duplicate attribute will now throw an Error exception instead of resulting in a fatal error.

In the SPL extension, attempting to clone an SplDirectory object will now throw an Error exception instead of resulting in a fatal error. Similarly, calling ArrayIterator::append() when iterating over an object will also now throw an Error exception.

In the standard extension, the assert() function, when provided with a string argument as its first parameter, will now throw a ParseError exception instead of resulting in a catchable fatal error if the PHP code is invalid. Similarly, calling forward_static_call() outside of a class scope will now throw an Error exception.

In the Tidy extension, creating a tidyNode manually will now throw an Error exception instead of resulting in a fatal error.

In the WDDX extension, a circular reference when serializing will now throw an Error exception instead of resulting in a fatal error.

In the XML-RPC extension, a circular reference when serializing will now throw an instance of Error exception instead of resulting in a fatal error.

In the Zip extension, the ZipArchive::addGlob() method will now throw an Error exception instead of resulting in a fatal error if glob support is not available.

Lexically bound variables cannot reuse names

Variables bound to a closure via the use construct cannot use the same name as any superglobals, $this, or any parameter. For example, all of these function definition will result in a fatal error:

<?php
$f 
= function () use ($_SERVER) {};
$f = function () use ($this) {};
$f = function ($param) use ($param) {};

long2ip() parameter type change

long2ip() now expects an int instead of a string.

JSON encoding and decoding

The serialize_precision ini setting now controls the serialization precision when encoding doubles.

Decoding an empty key now results in an empty property name, rather than _empty_ as a property name.

<?php
var_dump
(json_decode(json_encode(['' => 1])));

上の例の出力は、 たとえば以下のようになります。

object(stdClass)#1 (1) {
  [""]=>
  int(1)
}

When supplying the JSON_UNESCAPED_UNICODE flag to json_encode(), the sequences U+2028 and U+2029 are now escaped.

Changes to mb_ereg() and mb_eregi() parameter semantics

The third parameter to the mb_ereg() and mb_eregi() functions (regs) will now be set to an empty array if nothing was matched. Formerly, the parameter would not have been modified.

Drop support for the sslv2 stream

The sslv2 stream has now been dropped in OpenSSL.