下位互換性のない変更点
PHP コア
ヒアドキュメント/Nowdoc の終了ラベルの解釈
ヒアドキュメント/Nowdoc の文法が柔軟になった ことにより、本体の内部に終了ラベルが含まれた ドキュメンテーション文字列は、エラーが発生するか、解釈の振る舞いが変わる可能性があります。 たとえば、以下のような場合です:
<?php
$str = <<<FOO
abcdefg
FOO
FOO;
?>
FOO
が入ったとしても、以前は特別な意味は何もありませんでした。
ですが、このバージョンからは ヒアドキュメントの終了と解釈され、
後に続く FOO;
が syntax error になるでしょう。
この問題は、文字列の内容に決して含まれることのない終了ラベルを選ぶことで常に回避できます。
switch の制御フローを変更する continue 文は警告が出る
switch
の制御フローを変更することを狙った
continue
文は、警告が出るようになりました。
PHP では、このような continue
文は
break
と同等で、他のプログラミング言語では
continue 2
と同じように振る舞うのとは対照的です。
<?php
while ($foo) {
switch ($bar) {
case "baz":
continue;
// Warning: "continue" targeting switch is equivalent to
// "break". Did you mean to use "continue 2"?
}
}
?>
ArrayAccess を実装したオブジェクトに対する、 数値形式の文字列キーの解釈が厳密に
$obj
が ArrayAccess
を実装したオブジェクトで、
"123"
が数値の文字列リテラルだった場合、
この "123"
は暗黙のうちに整数型に変換されなくなりました。
つまり、$obj->offsetGet(123)
ではなく、
$obj->offsetGet("123")
がコールされるようになります。
これは、リテラルでない値の既存の振る舞いに一致します。
配列の振る舞いには全く影響しません。
配列については、数値の文字列リテラルのキーは、整数型に暗黙のうちに変換され続けます。
static なプロパティが参照の代入によって分裂しなくなった
PHP では、子クラスで明示的にオーバーライドされない限り、static なプロパティが継承関係にあるクラスの間で共有されます。しかし、 実装上の副作用により、参照を代入することによって、static なプロパティが異なる値になる可能性がありました。こうした抜け穴がこのバージョンでは修正されました。
<?php
class Test {
public static $x = 0;
}
class Test2 extends Test { }
Test2::$x = &$x;
$x = 1;
var_dump(Test::$x, Test2::$x);
// Previously: int(0), int(1)
// Now: int(1), int(1)
?>
配列から返される参照とプロパティのアクセスは、即座に分割される
配列から返された参照と、プロパティのアクセスは、 アクセスの一部として別に扱われるようになりました。 これは、配列へのアクセスと、配列の値を使う間に、値を変更できなくなったということです。
<?php
$arr = [1];
$ref =& $arr[0];
var_dump($arr[0] + ($arr[0] = 2));
// Previously: int(4), Now: int(3)
?>
Traversable への引数のアンパックを整数でないキーで行うことはサポートされない
Traversable への引数のアンパックを整数でないキーで行うコードは動作しなくなりました。 次のようなコードが、 PHP 5.6 から 7.2 の間は偶然動いていました。
<?php
function foo(...$args) {
var_dump($args);
}
function gen() {
yield 1.23 => 123;
}
foo(...gen());
?>
その他雑多な変更
ext_skel ユーティリティは、 新しいオプションで完全に再設計され、いくつかの古いオプションは削除されました。 このユーティリティは、PHP で書かれており、それ以外の外部への依存はありません。
BeOS のサポートが削除されました。
EH_THROW
モードの、警告を自動的に例外に変換することで
スローされる例外(e.g. いくつかの DateTime 例外)
は、error_get_last() 関数の状態を収集しなくなりました。
そうした例外は、手動でスローされる例外と同じように動くようになります。
TypeError は、integer
と
boolean
ではなく、
それぞれ int
と bool
を誤った型として報告するようになります。
compact() 関数に渡された未定義の値は、NOTICEレベルの警告を発生させるようになります。
getimagesize() 関数と関連する関数は、BMP画像の MIME Type
を image/x-ms-bmp
ではなく
image/bmp
と報告するようになりました。
なぜなら、後者は IANA に登録されているから (» RFC 7903 を参照) です。
stream_socket_get_name() 関数は、
ブラケットでラップされた IPv6 アドレスを返すようになります。
たとえば、"::1:1337"
ではなく、
"[::1]:1337"
を返すようになるでしょう。
BCMath
BCMath 関数 でスローされる全ての例外は、 PHP のエラーハンドリングの機構を使うようになりました。 以前は、いくつかのエラーが stderr に直接出力されていました。
bcmul() および bcpow() 関数は、指定された精度の数値を返すようになりました。 以前は、返される値の後ろが、0埋めされることで省略される可能性がありました。
IMAP, POP3 および NNTP
rsh/ssh ログインはデフォルトで無効になりました。 これらを有効にしたい場合、imap.enable_insecure_rsh を使って下さい。 IMAPライブラリは rsh/ssh コマンドに渡す前にメールボックス名をフィルタしないので、 rsh/ssh を有効にした状態で この関数に信頼できないデータを渡すことは安全ではありません。
マルチバイト文字列
名前付きキャプチャのサポートが追加されたことにより、
mb_ereg_*()
におけるパターンに名前付きキャプチャを使うと、これまでと異なる振る舞いをします。
特に、名前付きキャプチャが matches の一部になった場合、
mb_ereg_replace() はこれを追加の文法に従って解釈します。
さらに詳しい情報は、名前付きキャプチャ
を参照ください。
MySQL 改良版拡張モジュール
プリペアドステートメント が、カラムに小数の桁数を指定する(e.g.
マイクロ秒を使う場合 TIMESTAMP(6)
のようにする)
ことによって、 DATETIME
, TIME
および
TIMESTAMP
型の秒の小数部を報告するようになりました。
以前のバージョンでは、秒の小数部は戻り値から単に省略されていました。
MySQL関数 (PDO_MYSQL)
プリペアドステートメント が、カラムに小数の桁数を指定する(e.g.
マイクロ秒を使う場合 TIMESTAMP(6)
のようにする)
ことによって、DATETIME
, TIME
および
TIMESTAMP
型の秒の小数部を報告するようになりました。
以前のバージョンでは、秒の小数部は戻り値から単に省略されていました。
この変更は、PDO_MYSQL
のプリペアドステートメントをエミュレートする機能を無効にしていた場合
(e.g つまり、MySQLネイティブなプリペアの機能を使っていた場合)
にのみ影響があることに注意して下さい。
PDO::ATTR_EMULATE_PREPARES
=true
(これはデフォルトです) にした接続を使う Statement は影響を受けず、
既に適切な秒の小数部をエンジンから取得していました。
リフレクション
リフレクション
を文字列にエクスポートした場合、integer
と
boolean
ではなく、int
と
bool
をそれぞれ使うようになりました。
Standard PHP Library (SPL)
SPL autoloader が例外をスローした場合、後に続く autoloader は実行されなくなりました。以前は、全ての autoloader が実行され、例外がチェインしていました。
SimpleXML
数学的な演算 に SimpleXML オブジェクトが含まれていた場合、テキストが int または float のうち、より適切なものとして扱われるようになりました。 以前は値が意図せず int として扱われた場合がありました。
外部から入力されるCookie
PHP 7.3.23 以降は、セキュリティ上の理由により、 外部から入力される Cookie の 名前 はurlデコードされなくなりました。