下位互換性のない変更点
関数に渡す引数が少ない場合の挙動
これまでのバージョンでは、ユーザー定義の関数に渡す引数が足りない場合は
warning が発生していました。PHP 7.1 以降では、warning ではなく
Error 例外が発生するようになります。
この変更はユーザー定義の関数に対してだけのもので、
内部関数には影響を及ぼしません。
スコープを調べる関数の動的呼び出しの禁止
ある種の関数について、動的な呼び出し
($func()
や array_map('extract', ...)
のような形式)
が使えなくなりました。対象になるのは、別のスコープを調べたり変更したり、
あいまいな挙動になってしまったりするような関数です。
この変更の影響を受ける関数は、以下のとおりです。
クラス、インターフェイス、トレイトに使えない名前
これらのキーワードが、クラスやインターフェイスやトレイトの名前として使えなくなりました。
mt_rand() のデフォルトが、修正版のメルセンヌ・ツイスタ
アルゴリズムを使うようになりました。mt_rand()
の結果に依存するコードを書いていた場合は、mt_srand()
のオプションの第二引数に MT_RAND_PHP
を指定すると、これまでの挙動 (間違った実装) を維持できます。
ASCII 制御文字 delete は識別子として使えない
ASCII 制御文字 delete (0x7F
) は、
クォートしない限りは識別子として使えなくなりました。
error_log
に syslog
を指定した場合の変更
INI 項目 error_log
の設定値を
syslog
にした場合に、PHP のエラーレベルが syslog
のエラーレベルにマッピングされるようになりました。
これまでのバージョンではすべてのエラーが notice レベルで記録されていましたが、
この変更によって、今までよりも細やかな区別ができるようになります。
未完成のオブジェクトのデストラクタは呼び出されない
オブジェクトのコンストラクタの実行中に例外がスローされた場合に、
そのオブジェクトのデストラクタが呼ばれることはなくなりました。
以前のバージョンでは、場合によっては
(例: そのオブジェクトが例外バックトレースなどで外部から参照される場合)
デストラクタが呼ばれることもありました。
文字列における空のインデックス演算子はサポートしない
文字列に空のインデックス演算子を適用する (例: $str[] = $x
)
と、fatal エラーが発生します。これまでのバージョンではエラーにならず、
ただ配列に変換されるだけでした。
空文字列に対して、文字列インデックス経由で値を設定する操作
空文字列に対して、一文字単位で変更する操作が、
空でない文字列と同じように機能するようになりました。
つまり、範囲外のオフセットに対する書き込みがスペースで埋められ、
整数型でない値は整数に変換され、最初の文字だけが採用されるというものです。
これより前のバージョンでは、黙って空の配列として扱われていました。
削除された INI 項目
以下の INI 項目は、削除されました。
-
session.entropy_file
-
session.entropy_length
-
session.hash_function
-
session.hash_bits_per_character
参照による代入で自動的に作られる配列の要素の並び順の変更
参照による代入で配列の要素が自動的に作られる場合に、その並び順が変更されました。
同値な要素の並び順
内部的なソートアルゴリズムが改良されたことに伴って、
比較したときに等しいとみなされる要素の並び順が以前とは変わるかもしれません。
注意:
同値な要素の並び順に依存するコードは書かないようにしましょう。
その並び順がいつまでも同じであるとは限りません。
E_RECOVERABLE エラーのエラーメッセージ
E_RECOVERABLE エラーのエラーメッセージが、
"Catchable fatal error" から
"Recoverable fatal error" に変更されました。
unserialize() 関数の $options パラメータ
unserialize() 関数の $options パラメータの
allowed_classes
要素が、
型を厳密に解釈するようになりました。
つまり、array または bool
以外のあらゆる値が与えられても、
unserialize() は false
を返し、
E_WARNING
レベルの警告が発生します。
DateTime クラスのコンストラクタに、マイクロ秒も組み込まれる
DateTime と DateTimeImmutable
は、現在時刻、明示的な時刻、
または相対時刻を示す文字列
(例: "first day of next month"
)
から構築されると、
マイクロ秒を適切に含めるようになりました。
これは、新しく生成されたふたつのインスタンスが、true
ではなくて
false
を返しやすくなったということです。
致命的なエラーが Error 例外に変換される
Date 拡張モジュールでは、
DateTime または DatePeriod
クラス のシリアライズデータが不正だったり、
シリアライズしたデータからタイムゾーンを初期化するのに失敗した場合、
致命的なエラーにならず、
__wakeup() や __set_state()
メソッドから Error 例外をスローするようになりました。
DBA 拡張モジュールでは、
(dba_insert() のように)
データを変更する関数は、キーが正確にふたつの要素を含んでいない場合に
キャッチ可能な fatal error ではなく、
Error 例外をスローするようになりました。
DOM 拡張モジュールでは、
不正なスキーマ や RelaxNG検証コンテキスト は
致命的なエラーにならず、
Error 例外をスローするようになりました。
同じように、適切な基底クラスを継承しないノードクラスを登録しようとしたり、
不正なプロパティを読み出そうとしたり、
読み込み専用のプロパティに書き込もうとしたりしても、
同様に Error 例外をスローようになりました。
IMAP 拡張モジュールでは、
16385 バイト以上の email アドレスは、
致命的なエラーにならず、
Error 例外をスローするようになりました。
Intl 拡張モジュールでは、
Collator クラスを継承したクラスで、
親メソッドを呼ぶ前に親のコンストラクタを呼ぶのに失敗すると、
回復可能な fatal error にはならず、
Error 例外をスローするようになりました。
同様に、Transliterator を clone すると、
内部の transliterator の複製に失敗した時に
致命的なエラーにならず、
Error 例外をスローするようになりました。
LDAP 拡張モジュールでは、
ldap_batch_modify() 関数に不明な変更タイプを渡すと、
致命的なエラーにならず、
Error 例外をスローするようになりました。
mbstring 拡張モジュールでは、
mb_ereg() 関数と
mb_eregi() 関数が、
'e' オプションを使い、かつ 不正な PHP の式が渡された場合に
ParseError 例外をスローするようになりました。
Mcrypt 拡張モジュールでは、
mcrypt_encrypt() と
mcrypt_decrypt() 関数が
mcrypt を初期化できなかった場合に
致命的なエラーにならず、
Error 例外をスローするようになりました。
mysqli 拡張モジュールでは、
不正なプロパティを読み出そうとしたり、
読み取り専用のプロパティに書き込もうとしたりすると、
致命的なエラーにならず、
Error 例外をスローするようになりました。
Reflection 拡張モジュールでは、
リフレクションオブジェクトを取得できなかったり、
オブジェクトのプロパティを取得できなかったりすると、
致命的なエラーにならず、
Error 例外をスローするようになりました。
Session 拡張モジュールでは、
セッションIDに文字列を返さないカスタムのセッションハンドラは、
セッションIDを生成しなければならない関数を呼んだ際に
致命的なエラーにならず、
Error 例外をスローするようになりました。
SimpleXML 拡張モジュールでは、
名前が付いていない、または 重複した属性を作ろうとすると、
致命的なエラーにならず、
Error 例外をスローするようになりました。
SPL 拡張モジュールでは、
SplDirectory オブジェクトを
clone しようとすると、
致命的なエラーにならず、
Error 例外をスローするようになりました。
同じように、オブジェクトを繰り返している時に
ArrayIterator::append() を呼び出すと、
Error 例外をスローするようになりました。
standard 拡張モジュールでは、
assert()関数 の
最初のパラメーターに string 型の引数が与えられた場合、
かつ PHP のコードが不正だった場合に
キャッチ可能な致命的なエラーではなく、
ParseError 例外をスローするようになりました。
同じように、
クラススコープの外側から
forward_static_call() を呼び出すと、
Error 例外をスローするようになりました。
Tidy 拡張モジュールでは、
tidyNode を手動で作ろうとすると、
致命的なエラーにならず、
Error 例外をスローするようになりました。
WDDX 拡張モジュールでは、
シリアライズする時に循環参照が存在すると、
致命的なエラーにならず、
Error 例外をスローするようになりました。
XML-RPC 拡張モジュールでは、
シリアライズする時に循環参照が存在すると、
致命的なエラーにならず、
Error 例外をスローするようになりました。
Zip 拡張モジュールでは、
glob サポートが利用できない場合、
ZipArchive::addGlob() メソッドは
致命的なエラーにならず、
Error 例外をスローするようになりました。
字句的に束縛される変数は、名前を再利用できない
use
経由で クロージャ
に束縛された変数名には、スーパーグローバル や
$this またはあらゆるパラメータ と同じ名前が使えなくなりました。
たとえば、次のような関数定義はすべて致命的なエラーが発生します。
JSON のエンコードとデコード
serialize_precision
ini 設定が、
float 型の値をエンコードするときに、
シリアル化の精度を制御するようになりました。
空のキーをデコードすると、
プロパティ名が _empty_
ではなく、空のプロパティ名になります。
json_encode() 関数に
JSON_UNESCAPED_UNICODE
フラグを渡すと、
U+2028 および U+2029 がエスケープされるようになりました。
mb_ereg() 関数 と
mb_eregi() 関数
の第3引数 (regs
) は、
マッチするものがなかった場合、空の配列が設定されるようになりました。
これより前のバージョンでは、このパラメータは変更されませんでした。
sslv2 ストリームのサポートの削除
sslv2 ストリーム が OpenSSL から削除されました。
戻り値の型が決まっている関数で "return;" と書いてもコンパイルエラーになる
戻り値の型を宣言している関数内で、引数がないreturn文を使うと、
(戻り値の型を void と宣言していない場合)
E_COMPILE_ERROR
が発生するようになりました。
これは、そのreturn文に到達しない場合であっても同じです。