下位互換性のない変更点

PHP コア

文字列と数値の比較

(厳密でないやり方で)数値と非数値文字列を比較する場合、 数値を文字列にキャストし、文字列と比較するようになりました。 数値と数値形式の文字列の比較は、以前と同じ振る舞いをします。 注意すべきなのは、これによって、 0 == "not-a-number"false と見なされるようになったことです。

比較 変更前 変更後
0 == "0" true true
0 == "0.0" true true
0 == "foo" true false
0 == "" true false
42 == " 42" true true
42 == "42foo" true false

その他の下位互換性のない変更

  • match が予約語になりました。

  • mixed が予約語になりました。 よって、クラスやインターフェイス、 トレイトの名前として使えなくなっています。 名前空間の中であっても同様です。

  • アサーションに失敗すると、デフォルトで例外をスローするようになりました。 古い振る舞いを望む場合、php.ini で assert.exception=0 と設定できます。

  • クラス名と同じ名前のメソッドは、コンストラクタと解釈されなくなりました。 __construct() メソッドを代わりに使って下さい。

  • static でないメソッドを、staticメソッドとしてコールできる機能が削除されました。 static でないメソッドをクラス名を使ってチェックした場合、 is_callable は失敗します。 (オブジェクトのインスタンスを使ってチェックしなければいけません)

  • (real)(unset) キャストが削除されました。

  • track_errors ini ディレクティブは削除されました。 つまり、php_errormsg が利用できなくなったということです。 代わりに error_get_last 関数が使えます。

  • 大文字小文字を区別しない定数を定義できる機能が削除されました。 define 関数の第3引数はもはや true ではありません。

  • __autoload 関数を使ってオートローダーを指定する機能は削除されました。 代わりに spl_autoload_register を使うべきです。

  • set_error_handler 関数で設定されるカスタムエラーハンドラには、 errcontext 引数は渡されなくなりました。

  • create_function 関数は削除されました。 無名関数が代わりに使えます。

  • each 関数は削除されました。 代わりに foreachArrayIterator を使うべきです。

  • Closure::fromCallableReflectionMethod::getClosure を使って メソッドから生成されたクロージャーから this の束縛を解除できる機能は削除されました。

  • this を使っている適切なクロージャーから、 this の束縛を解除する機能も削除されています。

  • オブジェクトに対して array_key_exists 関数を使える機能は削除されました。 isset または property_exists を代わりに使えます。

  • array_key_exists 関数の引数 key の型に関する振る舞いが、 isset 関数や配列アクセスの場合と一貫したものになりました。 全てのキーの型は通常の強制が行われ、配列やオブジェクトのキーは TypeError がスローされるようになりました。

  • はじめの数値のキーとして n を持つ配列は、 たとえ n が負の値であっても、 次の暗黙のキーは n+1 を使うようになります。

  • デフォルトの error_reporting のレベルは E_ALL になりました。 これより前のバージョンでは、 E_ALL から E_NOTICEE_DEPRECATED が除かれていました。

  • display_startup_errors は、 デフォルトで有効になりました。

  • 親クラスがないクラスの内部で parent を使うと、 致命的なコンパイルエラーが発生するようになりました。

  • @ 演算子は、致命的なエラー (E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR, E_PARSE) を隠さなくなりました。 @ を使う時に、 error_reporting が 0 であることを期待しているエラーハンドラは、 代わりにマスクチェックを調整すべきです:

    <?php
    // こういうエラーハンドラは
    function my_error_handler($err_no$err_msg$filename$linenum) {
        if (
    error_reporting() == 0) {
            return 
    false;
        }
        
    // ...
    }

    // 以下に置き換えましょう
    function my_error_handler($err_no$err_msg$filename$linenum) {
        if (!(
    error_reporting() & $err_no)) {
            return 
    false;
        }
        
    // ...
    }
    ?>

    さらに、実運用環境で表示されていなかった、 情報のリークに繋がるエラーメッセージにも注意を払うべきです。 エラーのロギングと併せて、 display_errors=Off となっていることを確認するようにして下さい。

  • #[ は、コメントの開始として解釈されなくなりました。 この文法は、アトリビュート として使われるようになっているからです。

  • 非互換なメソッドのシグネチャによる継承エラー(リスコフの置換原則違反)については、 常に致命的なエラーが生成されるようになりました。 これより前のバージョンでは、警告が生成される場合がありました。

  • ビットシフトや加算、減算に対する連結演算子の優先順位が変更されました。

    <?php
    echo "Sum: " $a $b;
    // 上記は、以前のバージョンでは以下のように解釈されていました:
    echo ("Sum: " $a) + $b;
    // PHP 8.0.0 からは、以下のように解釈されます:
    echo "Sum:" . ($a $b);
    ?>

  • 実行時に null に解決されるデフォルト値を持つ引数は、 引数の型を暗黙のうちに nullable とマークすることはなくなりました。 明示的に nullable と宣言するか、 明示的にデフォルト値を null と宣言しなければなりません。

    <?php
    // 以下のようなコードは
    function test(int $arg CONST_RESOLVING_TO_NULL) {}
    // このように置き換えるか
    function test(?int $arg CONST_RESOLVING_TO_NULL) {}
    // こう書きましょう
    function test(int $arg null) {}
    ?>

  • たくさんの警告が Error 例外に変換されるようになりました:

    • オブジェクトでない値にプロパティを書き込もうとした場合。 これより前のバージョンでは、 null については stdClass オブジェクトが暗黙のうちに作られ、 空文字列については false となっていました。
    • PHP_INT_MAX キーが既に使われている配列に対して、 要素を追加しようとした場合。
    • 不正な型(配列やオブジェクト) を配列のキーや文字列のオフセットとして使おうとした場合。
    • スカラー値に配列のインデックスを書き込もうとした場合
    • 配列やTraversable でない値をアンパックしようとした場合
    • 未定義の、非修飾の定数にアクセスしようとした場合。 これより前のバージョンでは、 非修飾の定数にアクセスしようとすると、警告が発生し、 文字列として解釈されていました。
    • 可変長引数でない組み込み関数に、間違った数の引数を渡した場合、 ArgumentCountError がスローされるようになりました。

    多くの notice が警告に変換されるようになりました:

    • 未定義の変数を読み取ろうとした場合
    • 未定義のプロパティを読み取ろうとした場合
    • 未定義の配列のキーを読み取ろうとした場合
    • オブジェクトでない値のプロパティを読み取ろうとした場合
    • 配列でない値のインデックスにアクセスしようとした場合
    • 配列を文字列に変換しようとした場合
    • リソースを配列のキーとして使おうとした場合
    • null や bool 値や float の値を文字列オフセットとして使おうとした場合
    • 境界を超えて文字列のオフセットを読み取ろうとした場合
    • 文字列のオフセットに空文字列を割り当てようとした場合

  • 文字列のオフセットに複数バイトを割り当てようとすると、警告が発生するようになりました。

  • ソースファイル中に(文字列の範囲外のNUL バイトのような) 想定外の文字が含まれていた場合、 コンパイル時に警告を出す代わりに、 ParseError がスローされるようになりました。

  • 例外がキャッチされなかった場合、 "クリーンなシャットダウン" が行われます。 これは、例外がキャッチされなかった後、 デストラクタが呼ばれるということです。

  • コンパイル時の致命的なエラー "Only variables can be passed by reference" は、 実行時まで遅延され、 "Argument cannot be passed by reference" という Error 例外に変換されるようになりました。

  • "Only variables should be passed by reference" という警告は、 "Argument cannot be passed by reference" という例外に変換されるようになりました。

  • 無名クラスのために生成される名前が変更されました。 最初の親クラスやインターフェイスの名前が含まれるようになっています:

    <?php
    new class extends ParentClass {};
    // -> ParentClass@anonymous
    new class implements FirstInterfaceSecondInterface {};
    // -> FirstInterface@anonymous
    new class {};
    // -> class@anonymous
    ?>

    上で示した名前の後に、NULバイトやユニークなサフィックスが続きます。

  • トレイトのエイリアス調整において、 クラス名を指定していないメソッド参照は、 曖昧でないことが必須になりました:

    <?php
    class {
        use 
    T1T2 {
            
    func as otherFunc;
        }
        function 
    func() {}
    }
    ?>

    T1::func()T2::func() が両方存在している場合、 PHP 8.0.0 より前のバージョンでは、 このコードは黙って動作し、func は T1::func を参照するものと想定されていました。 PHP 8.0.0 からは、このコードは致命的なエラーが発生します。 T1::func または T2::func を明示的に書く必要があります。

  • トレイトで定義される抽象メソッドのシグネチャは それを実装するクラスのメソッド側で、 一致しているかがチェックされるようになりました:

    <?php
    trait MyTrait {
        abstract private function 
    neededByTrait(): string;
    }

    class 
    MyClass {
        use 
    MyTrait;

        
    // エラー。戻り値の型が一致しません。
        
    private function neededByTrait(): int { return 42; }
    }
    ?>

  • 無効にされている関数は、存在しない関数であるかのように扱われるようになりました。 無効にされている関数を呼び出しても unknown と報告されますし、 無効にされている関数を再定義することも可能になっています。

  • data:// ストリームラッパーは書き込み可能ではなくなりました。 これは、ドキュメント化されている振る舞いに一致します。

  • 算術演算子とビット演算子 +, -, *, /, **, %, <<, >>, &, |, ^, ~, ++, -- は、オペランドのひとつが配列だったり、 リソース だったり、オーバーロードされていない object だったりした場合に、 一貫して TypeError をスローするようになりました。 これに対する唯一の例外は、配列と配列を + でマージする操作で、 これはまだサポートされています。

  • float 型から文字列型へのキャストは、 ロケールに依存しないように常に振る舞うようになります。

    <?php
    setlocale
    (LC_ALL"de_DE");
    $f 3.14;
    echo 
    $f"\n";
    // PHP 8.0.0 より前のバージョン: 3,14
    // PHP 8.0.0 以降:        3.14
    ?>

    数値のフォーマットをカスタマイズする方法については、 printf, number_format 関数 および NumberFormatter メソッドを参照ください。

  • 推奨されなくなっていた、 オフセットを指定してアクセスするための波括弧のサポートが削除されました。

    <?php
    // 以下ではなく:
    $array{0};
    $array{"key"};
    // このように書いて下さい:
    $array[0];
    $array["key"];
    ?>

  • private メソッドに final 修正子を指定した場合、 そのメソッドがコンストラクタでない限り、警告が発生するようになります。

  • オブジェクトのコンストラクタで exit が呼び出された場合、 オブジェクトのデストラクタはコールされなくなりました。 これは、コンストラクタが例外をスローしたときの振る舞いと一致します。

  • 名前空間に含まれる名前には、 ホワイトスペースを含めることができなくなりました。 つまり、Foo\Bar は名前空間の名前として認識されますが Foo \ Bar は認識されなくなったということです。 逆に、予約語のキーワードは名前空間の一部として許されるようになりました。 これによって、コードの解釈が変わるかもしれません。 new\xconstant('new\x') と同じですが、 new \x() とは異なります。

  • 三項演算子をネストする場合、明示的に括弧が必要になりました。

  • debug_backtraceException::getTrace メソッド は、引数にリファレンスを取らなくなりました。 これにより、バックトレースを通じて、関数の引数を変更できなくなります。

  • 数値形式の文字列の扱いが、より直感的で間違いにくいものに変更されました。 ホワイトスペースが前に付いている場合の扱いと一貫性を持たせるため、 数値形式の文字列の後にホワイトスペースを付けることが許されるようになりました。 これがもっとも影響するのは以下です:

    • is_numeric 関数
    • 文字列同士の比較
    • 型宣言
    • インクリメントとデクリメント演算

    "数値が始めに来る文字列" の概念は殆どなくなっています; このケースは、移行を容易にするために存在しています。 "A non well-formed numeric value encountered" という E_NOTICE が発生する文字列 は、"A non-numeric value encountered" という E_WARNING が発生するようになっています。 そして、"A non-numeric value encountered" という E_WARNING が発生していた全ての文字列は、 TypeError が発生するようになりました。 これが最も影響するのは、以下の場合です:

    • 算術演算
    • ビット演算

    この E_WARNING から TypeError への変更は、 不正な文字列オフセットの場合に発生する "Illegal string offset 'string'" という E_WARNING にも影響します。 文字列から int/float に明示的にキャストする場合の振る舞いは変更されていません

  • マジックメソッドは引数と戻り値の型を持ち、 宣言された場合はチェックが行われるようになりました。 シグネチャは次の一覧と一致させるべきです:

    • __call(string $name, array $arguments): mixed
    • __callStatic(string $name, array $arguments): mixed
    • __clone(): void
    • __debugInfo(): ?array
    • __get(string $name): mixed
    • __invoke(mixed $arguments): mixed
    • __isset(string $name): bool
    • __serialize(): array
    • __set(string $name, mixed $value): void
    • __set_state(array $properties): object
    • __sleep(): array
    • __unserialize(array $data): void
    • __unset(string $name): void
    • __wakeup(): void

  • call_user_func_array 関数に渡される 配列のキーは、引数名として解釈されるようになりました。 これより前のバージョンでは、静かに無視されていました。

  • 名前空間の内部で assert() と呼ばれる関数を宣言する ことは許されなくなり、 E_COMPILE_ERROR が発生するようになりました。 assert 関数は PHP エンジンによって特別扱いを受けることになっているので、 名前空間の内部で同じ名前が定義されていると、 動作が一貫しなくなる原因になるからです。

リソースからオブジェクトへの移行

いくつかの リソース が、object に移行しました。 is_resource 関数を使って戻り値をチェックしているコードは、 false を返すことをチェックするコードに置き換えるべきです。

  • curl_init 関数は リソース ではなく、CurlHandle オブジェクトを返すようになりました。 curl_close 関数はもはや意味をなしません。 CurlHandle インスタンスは、 参照されなくなった場合に、自動的に破棄されます。

  • curl_multi_init 関数は リソース ではなく、CurlMultiHandle オブジェクトを返すようになりました。 curl_multi_close 関数はもはや意味をなしません。 CurlMultiHandle インスタンスは、 参照されなくなった場合に、自動的に破棄されます。

  • curl_share_init 関数は リソース ではなく、CurlShareHandle オブジェクトを返すようになりました。 curl_share_close 関数はもはや意味をなしません。 CurlShareHandle インスタンスは、 参照されなくなった場合に、自動的に破棄されます。

  • enchant_broker_init 関数は リソース ではなく、EnchantBroker オブジェクトを返すようになりました。

  • enchant_broker_request_dictenchant_broker_request_pwl_dict 関数は リソース ではなく、EnchantDictionary オブジェクトを返すようになりました。

  • GD 拡張モジュールは 画像の基本的なデータ構造として リソース ではなく、GdImage オブジェクトを使うようになりました。 imagedestroy 関数はもはや意味をなしません。 GdImage インスタンスは、 参照されなくなった場合に、自動的に破棄されます。

  • openssl_x509_readopenssl_csr_sign 関数は リソース ではなく、OpenSSLCertificate オブジェクトを返すようになりました。 openssl_x509_free 関数は非推奨となり、 もはや意味をなしません。 OpenSSLCertificate インスタンスは、 参照されなくなった場合に、自動的に破棄されます。

  • openssl_csr_new 関数は リソース ではなく、OpenSSLCertificateSigningRequest オブジェクトを返すようになりました。

  • openssl_pkey_new 関数は リソース ではなく、OpenSSLAsymmetricKey オブジェクトを返すようになりました。 openssl_pkey_free 関数は非推奨となり、 もはや意味をなしません。 OpenSSLAsymmetricKey インスタンスは、 参照されなくなった場合に、自動的に破棄されます。

  • shmop_open 関数は リソース ではなく、Shmop オブジェクトを返すようになりました。 shmop_close 関数は非推奨となり、 もはや意味をなしません。 Shmop インスタンスは、 参照されなくなった場合に、自動的に破棄されます。

  • socket_create, socket_create_listen, socket_accept, socket_import_stream, socket_addrinfo_connect, socket_addrinfo_bind, socket_wsaprotocol_info_import 関数は リソース ではなく、Socket オブジェクトを返すようになりました。 socket_addrinfo_lookup 関数は リソース ではなく、AddressInfo オブジェクトを返すようになりました。

  • msg_get_queue 関数は リソース ではなく、SysvMessageQueue オブジェクトを返すようになりました。

  • sem_get 関数は リソース ではなく、SysvSemaphore オブジェクトを返すようになりました。

  • shm_attach 関数は リソース ではなく、SysvSharedMemory オブジェクトを返すようになりました。

  • xml_parser_createxml_parser_create_ns 関数は リソース ではなく、XMLParser オブジェクトを返すようになりました。 xml_parser_free 関数はもはや意味をなしません。 XMLParser インスタンスは、 参照されなくなった場合に、自動的に破棄されます。

  • XMLWriter 関数リソース ではなく、XMLWriter オブジェクトを受け入れ、返すようになりました。

  • inflate_init 関数は リソース ではなく、InflateContext オブジェクトを返すようになりました。

  • deflate_init 関数は リソース ではなく、DeflateContext オブジェクトを返すようになりました。

COM および .Net (Windows)

タイプライブラリ から 大文字小文字を区別せずに定数をインポートする機能は削除されました。 com_load_typelib 関数の第二引数は もはや false ではありません。 com.autoregister_casesensitive はもはや無効ではなくなりました。 つまり、com.typelib_file の #case_insensitive マーカーは無視されます。

CURL

CURLOPT_POSTFIELDS は、 オブジェクトを配列として受け入れなくなりました。 オブジェクトを配列として解釈させるためには、 明示的に (array) キャストを行って下さい。 配列を受け入れる他のオプションにも、同じことが当てはまります。

日付と時刻

mktimegmmktime 関数は 少なくともひとつ引数が必要になりました。 現在のタイムスタンプを取得する用途には time 関数が使えます。

DOM

DOM 拡張モジュールで実装されておらず、振る舞いも持たず、 テストデータもないクラスが削除されました。 これらのクラスは、最新のDOM標準からも削除されています:

  • DOMNameList
  • DomImplementationList
  • DOMConfiguration
  • DomError
  • DomErrorHandler
  • DOMImplementationSource
  • DOMLocator
  • DOMUserDataHandler
  • DOMTypeInfo
  • DOMStringExtend

DOM 拡張モジュールで実装されておらず、 振る舞いも持たない以下のメソッドが削除されました:

  • DOMNamedNodeMap::setNamedItem
  • DOMNamedNodeMap::removeNamedItem
  • DOMNamedNodeMap::setNamedItemNS
  • DOMNamedNodeMap::removeNamedItemNS
  • DOMText::replaceWholeText
  • DOMNode::compareDocumentPosition
  • DOMNode::isEqualNode
  • DOMNode::getFeature
  • DOMNode::setUserData
  • DOMNode::getUserData
  • DOMDocument::renameNode

Enchant

  • enchant_broker_list_dicts, enchant_broker_describe, enchant_dict_suggest 関数は、 null ではなく、空の配列を返すようになりました。

Exif

read_exif_data 関数は削除されました。 exif_read_data 関数を代わりに使うべきです。

フィルタ

  • FILTER_VALIDATE_URL フラグのための定数 FILTER_FLAG_SCHEME_REQUIREDFILTER_FLAG_HOST_REQUIRED が削除されました。 schemehost は(かつてもそうでしたが) 常に必須です。

  • filter_input 関数などで使われている定数 INPUT_REQUESTINPUT_SESSION は削除されました。 これらは実装されたことがなく、使うと常に警告が発生していました。

GD

  • 推奨されなくなっていた image2wbmp 関数は削除されました。

  • 推奨されなくなっていた関数 png2wbmpjpeg2wbmp が削除されました。

  • imagecropauto 関数の mode 引数のデフォルトは -1 ではなくなりました。 IMG_CROP_DEFAULT を代わりに使うべきです。

  • Windows では、php_gd2.dll の名前が、php_gd.dll に変更されました。

GMP

gmp_random 関数は削除されました。 gmp_random_rangegmp_random_bits 関数を代わりに使うべきです。

Iconv

エラーが発生した時に errno を適切に設定していなかった iconv の実装はもはやサポートされなくなりました。

IMAP

  • imap_headerinfo 関数で 未使用になっていた default_host 引数が削除されました。

  • imap_headerinfo 関数のエイリアスだった imap_header 関数は削除されました。

国際化関数

  • 推奨されなくなっていた定数 INTL_IDNA_VARIANT_2003 が削除されました。

  • 推奨されなくなっていた定数 Normalizer::NONE が削除されました。

LDAP

  • 推奨されなくなっていた関数 ldap_sort, ldap_control_paged_result, ldap_control_paged_result_response は削除されました。

  • ldap_set_rebind_proc のインターフェイスが変更されました。 callback 引数は空文字列を受け入れなくなりました。 null を代わりに使うべきです。

マルチバイト文字列

  • INI ディレクティブ mbstring.func_overload は削除されました。 関連する定数 MB_OVERLOAD_MAIL, MB_OVERLOAD_STRING, MB_OVERLOAD_REGEX も削除されています。 mb_get_info 関数の "func_overload""func_overload_list" エントリも削除されています。

  • mb_parse_str は、 結果の配列を指定しないと使えなくなりました。

  • たくさんの mbregex の関数エイリアスが削除されました。 どの関数を代わりに使うべきなのかは、以下の一覧を参照ください:

    • mbregex_encodingmb_regex_encoding
    • mberegmb_ereg
    • mberegimb_eregi
    • mbereg_replacemb_ereg_replace
    • mberegi_replacemb_eregi_replace
    • mbsplitmb_split
    • mbereg_matchmb_ereg_match
    • mbereg_searchmb_ereg_search
    • mbereg_search_posmb_ereg_search_pos
    • mbereg_search_regsmb_ereg_search_regs
    • mbereg_search_initmb_ereg_search_init
    • mbereg_search_getregsmb_ereg_search_getregs
    • mbereg_search_getposmb_ereg_search_getpos
    • mbereg_search_setposmb_ereg_search_setpos

  • mb_ereg_replace 関数の e 修正子が削除されました。 mb_ereg_replace_callback 関数を代わりに使って下さい。

  • mb_ereg_replace 関数に文字列でないパターン引数を渡すと、 ASCII コードポイントではなく、文字列として解釈されるようになりました。 以前のバージョンの振る舞いは、 明示的に chr 関数を呼び出すことで復元できます。

  • mb_strpos, mb_strrpos, mb_stripos, mb_strripos, mb_strstr, mb_stristr, mb_strrchr, mb_strrichr 関数の needle 引数は、空に出来るようになりました。

  • mb_decode_numericentity 関数で内部的に使われていなかった 引数 is_hex は削除されました。

  • mb_strrpos 関数の第三引数に、 オフセットではなくエンコーディングを渡していた古い振る舞いは削除されました。 明示的にオフセットに 0 を渡し、 第四引数にエンコーディングを渡す方法を代わりに使うべきです。

  • 文字エンコーディング ISO_8859-* のエイリアスは ISO8859-* に置き換えられました。 これは、iconv 拡張モジュールと相互運用性を向上させるためです。 アンダースコア付きの mbregex の ISO 8859 aliases (ISO_8859_*ISO8859_*) も削除されています。

  • mb_eregmb_eregi 関数は、 マッチに成功した場合に true を返すようになりました。 これより前のバージョンでは、 matches が渡されなかった場合に 整数 1 が返されていました。 matches が渡された場合には max(1, strlen($matches[0])) が返されていました。

OCI8

  • OCI-Lob クラスは OCILob と呼ばれるようになり、 OCI-Collection クラスは OCICollection と呼ばれるようになりました。 これは、PHP 8 の arginfo 型アノテーションツールの 名前に関する規約で強制されたものです。

  • いくつかの関数エイリアスが推奨されなくなりました。

  • oci_internal_debug 関数と そのエイリアス ociinternaldebug は削除されました。

ODBC

  • odbc_connect 関数は 接続を使い回さなくなりました。

  • odbc_exec 関数で使われていなかった flags 引数が削除されました。

OpenSSL

  • openssl_sealopenssl_open 関数には method を渡すことが必須になりました。 なぜなら、以前のデフォルト値 "RC4" はセキュアでないと見なされているからです。

正規表現 (Perl互換)

不正なエスケープシーケンスを渡した場合、 もはやリテラルと解釈されなくなりました。 リテラルと解釈する振る舞いは X 修正子で必須でしたが、 無視されるようになっています。

PHP Data Objects(PDO)

  • デフォルトのエラーハンドリングのモードが "silent" から "exceptions" に変更されました。 詳細は Errors とエラーハンドリング を参照ください。

  • いくつかの PDOクラスのメソッドシグネチャが変更されました:

    • PDO::query(string $query, ?int $fetchMode = null, mixed ...$fetchModeArgs)
    • PDOStatement::setFetchMode(int $mode, mixed ...$args)

PDO ODBC

php.ini ディレクティブ pdo_odbc.db2_instance_name は削除されました。

PDO MySQL

PDO::inTransaction は、 PDO が管理しているおおよその情報ではなく、 実際のトランザクションの状態を報告するようになりました。 クエリが "暗黙のコミット" に依存していた場合、 PDO::inTransaction は後に false を返します。 なぜなら、トランザクションが既にアクティブではないからです。

PostgreSQL

  • pg_connect 関数で 推奨されなくなっていた、 接続文字列の代わりに複数の引数を受け入れる文法は もはやサポートされなくなりました。

  • 推奨されなくなっていた pg_lo_importpg_lo_export 関数の、 最後の引数で接続を渡すシグネチャはサポートされなくなりました。 代わりに、接続は最初の引数で渡すべきです。

  • pg_fetch_all 関数 は 結果セットの行が0行の場合に、false ではなく空の配列を返すようになりました。

Phar

phar に関連付けられたメタデータは、自動的にアンシリアライズされなくなりました。 これは、オブジェクトのインスタンス化やオートローディングなどに起因する、 潜在的なセキュリティ上の脆弱性を修正するためです。

リフレクション

  • メソッドシグネチャに関する変更

    • ReflectionClass::newInstance($args)
    • ReflectionFunction::invoke($args)
    • ReflectionMethod::invoke($object, $args)

    は、以下のように変更されました:

    • ReflectionClass::newInstance(...$args)
    • ReflectionFunction::invoke(...$args)
    • ReflectionMethod::invoke($object, ...$args)

    PHP 7 と PHP 8 の間で互換性を保たなければならないコードは、 両方のバージョンで互換性を取るために、以下のようなシグネチャが使えます:

    • ReflectionClass::newInstance($arg = null, ...$args)
    • ReflectionFunction::invoke($arg = null, ...$args)
    • ReflectionMethod::invoke($object, $arg = null, ...$args)

  • ReflectionType::__toString メソッドは、 完全な型のデバッグ用の文字列表現を返すようになり、非推奨ではなくなりました。 特に、nullable な型に対しては、nullを代入できることを示す情報が含まれるようになります。 戻り値のフォーマットは安定しておらず、PHP のバージョンによって変わる可能性があります。

  • リフレクションの export() メソッドは削除されました。 代わりに、リフレクションオブジェクトを文字列にキャストすることができます。

  • ReflectionMethod::isConstructorReflectionMethod::isDestructor メソッドは インターフェイスの __construct()__destruct() についても true を返すようになりました。 これより前のバージョンでは、クラスとトレイトのメソッドに対してだけ true を返していました。

  • ReflectionType::isBuiltin メソッドは、 ReflectionNamedType クラスに移動しました。 ReflectionUnionType クラスには存在しなくなっています。

Sockets

  • 推奨されなくなっていた socket_addrinfo_lookup 関数の flags に指定する AI_IDN_ALLOW_UNASSIGNED および AI_IDN_USE_STD3_ASCII_RULES は削除されました。

Standard PHP Library (SPL)

  • SplFileObject::fgetss メソッドは削除されました。

  • SplFileObject::seek は、 常に行の先頭にシークするようになりました。 これより前のバージョンでは、 >=1 を position に指定すると、次の行の先頭を探していました。

  • SplHeap::compare はメソッドシグネチャを指定するようになりました。 このメソッドを実装する継承先のクラスは、 互換性のあるメソッドシグネチャを持たなければなりません。

  • SplDoublyLinkedList::push, SplDoublyLinkedList::unshift および SplQueue::enqueue は、true ではなく void を返すようになりました。

  • spl_autoload_register 関数は、 引数が不正な場合には常に TypeError を発生させるようになりました。 よって、2番目の引数 do_throw は無視され、 false を設定すると、警告が発生します。

  • SplFixedArray クラスは Iterator ではなく IteratorAggregate を実装しました。 SplFixedArray::rewind, SplFixedArray::current, SplFixedArray::key, SplFixedArray::next, SplFixedArray::valid は削除されました。 代替として、 SplFixedArray::getIterator が追加されました。 SplFixedArray を通じて明示的にイテレーションを行うあらゆるコードは、 SplFixedArray::getIterator メソッドを使い Iterator を取得しなければなりません。 これは、SplFixedArray がネストされたループ中で安全に使えるようになったということです。

標準ライブラリ

  • assert 関数は 文字列の引数を評価しなくなりました。 代わりに、他の引数と同じように扱われます。 assert('$a == $b') ではなく assert($a == $b) を使うべきです。 INI ディレクティブ assert.quiet_eval と 定数 ASSERT_QUIET_EVAL も削除されました。 なぜなら、もはや何の効果も無いからです。

  • parse_str は、 結果の配列を指定しなければ使えなくなりました。

  • string.strip_tags フィルタは削除されました。

  • strpos, strrpos, stripos, strripos, strstr, strchr, strrchr, stristr 関数の needle 引数は常に文字列として解釈されるようになりました。 これより前のバージョンでは、 文字列でない引数は ASCII コードポイントと解釈されていました。 chr 関数を明示的に呼ぶことで、 以前の振る舞いを復元できます。

  • strpos, strrpos, stripos, strripos, strstr, stristr, strrchr 関数の needle 引数は、空に出来るようになりました。

  • substr, substr_count, substr_compare, iconv_substr 関数の length 引数は null も指定できるようになりました。 null を指定した場合、 length 引数が指定されなかったことと同じように振る舞います。 よって、この場合、空文字列ではなく、残りの文字列を返します。

  • array_splice 関数の length 引数は null も指定できるようになりました。 null を指定した場合、引数を省略した場合と同じ振る舞いをします。 よって、offset から配列の最後までの全ての要素を削除する動きになります。

  • vsprintf, vfprintf, vprintf 関数の args 引数は、配列であることが必須になりました。 これより前のバージョンでは、あらゆる型の値を受け入れていました。

  • password_hash 関数の 'salt' オプションはサポートされなくなりました。 'salt' オプションを使うと警告が生成され、 指定された salt は無視されます。 そして生成された salt が代わりに使われます。

  • quotemeta 関数は、空文字列を渡すと空文字列を返すようになりました。 これより前のバージョンでは、false を返していました。

  • 以下の関数は削除されました:

    • hebrevc
    • convert_cyr_string
    • money_format
    • ezmlm_hash
    • restore_include_path
    • get_magic_quotes_gpc
    • get_magic_quotes_runtime
    • fgetss

  • 定数 FILTER_SANITIZE_MAGIC_QUOTES は削除されました。

  • ($pieces, $glue) のような形で、implode 関数を逆の引数の順番で呼ぶことはサポートされなくなりました。

  • parse_url 関数は、 query および fragment が存在しないことと、空であることを区別するようになりました:

    • http://example.com/foo → query = null, fragment = null
    • http://example.com/foo? → query = "", fragment = null
    • http://example.com/foo# → query = null, fragment = ""
    • http://example.com/foo?# → query = "", fragment = ""
    これより前のバージョンでは、上の全ての場合で、query と fragment の値が null になっていました。

  • var_dumpdebug_zval_dump 関数は INIディレクティブ precision ではなく serialize_precision を使って浮動小数点を印字するようになりました。 デフォルトの設定では、浮動小数点はこのデバッグ関数によって 全精度で印字されるようになるということです。

  • __sleep() が返す 配列に存在しないプロパティが含まれていた場合、 静かに無視されるようになりました。 これより前のバージョンでは、 そうしたプロパティは値 null を持つかのようにシリアライズされていました。

  • デフォルトの起動時のロケールは、常に "C" になりました。 デフォルトでは、どのロケールからも環境を継承しません。 これより前のバージョンでは、 LC_ALL"C" に設定されていましたが、 LC_CTYPE は環境から情報を継承していました。 しかしながら、関数によっては、明示的に setlocale を呼び出さないと 継承した環境を尊重しないものもあります。 ロケールをデフォルトから変えるためには、 setlocale 関数を明示的に呼ぶことが常に必須になりました。

  • 非推奨になっていた crypt 関数が DES にフォールバックする振る舞いが削除されました。 不明な salt フォーマットを crypt 関数に渡すと、 弱い DES ハッシュにフォールバックするのではなく、 *0 という値になり、失敗するようになります。

  • crypt 関数に、 SHA256/SHA512 の範囲外の round を指定すると、 最も近い境界値に切り詰めるのではなく、 *0 という値になり、失敗するようになりました。 これは、glibc の振る舞いと一致します。

  • 配列に比較結果が等しい要素が含まれている場合、ソートを行う関数の結果が変わる可能性があります。

  • コールバックを受け入れるあらゆる関数のうち、 リファレンスの引数を受け入れるように明示的に指定して「いない」 ものに対し、 リファレンスを使ったコールバックを渡すと警告が発生するようになりました。 例としては、 array_filterarray_reduce 関数があります。 これらでほとんどの関数の例を示していますが、全てではありません。

  • file_get_contents 関数のように、 関数が使うHTTPストリームラッパーは、 デフォルトで HTTP/1.0 ではなく、 HTTP/1.1 を指定するようになりました。 これによって、クライアントの振る舞いが変わるわけではありませんが、 サーバーが異なるレスポンスを返す可能性があります。 古い振る舞いをさせるには、 以下のようにして 'protocol_version' ストリームコンテキストオプションを設定して下さい。

    <?php
    $ctx 
    stream_context_create(['http' => ['protocol_version' => '1.0']]);
    echo 
    file_get_contents('http://example.org'false$ctx);
    ?>

  • 明示的に salt を指定せず crypt 関数を呼ぶことはサポートされなくなりました。 自動的に生成される salt で強いハッシュを生成したい場合、 代わりに password_hash を使って下さい。

  • substr, mb_substr, iconv_substr, grapheme_substr 関数は、 文字列の境界を越えたオフセットを一貫した形で処理するようになりました。 これより前のバージョンでは、空文字列ではなく false を返す場合がありました。

  • Windows では、 シェルを使い、プログラムを実行する関数 (proc_open, exec, popen など) は、 一貫して %comspec% /s /c "$commandline" を使うようになりました。 これは、(追加のクォート無しで) $commandline を実行することと同じです。

Sysvsem

  • sem_get 関数の auto_release 引数は、 int ではなく bool の値を受け入れるように変更されました。

Tidy

  • 内部的に使われていなかった use_include_path 引数が、 tidy_repair_string 関数から削除されました。

  • tidy::repairString, tidy::repairFile が、staticメソッドになりました。

Tokenizer

  • T_COMMENT トークンは最後の改行文字を含まなくなりました。 改行文字はその後に続く T_WHITESPACE トークンに含まれるようになります。 注意すべきなのは、 T_COMMENT の後にホワイトスペースが続くとは限らないことです。 T_CLOSE_TAG やファイルの終端が続く場合もありえます。

  • 名前空間の中にある名前は、 T_NAME_QUALIFIED (Foo\Bar), T_NAME_FULLY_QUALIFIED (\Foo\Bar), T_NAME_RELATIVE (namespace\Foo\Bar) トークンを使って表現されるようになりました。 T_NS_SEPARATOR トークンは 単独の名前空間の区切り文字としてだけ使われます。 そして、グループ化されたuse宣言と一緒に使った場合にだけ文法的に合法です。

XMLReader

XMLReader::open, XMLReader::xml が staticメソッドになりました。 これらは、まだインスタンスメソッドとして呼び出すことが出来ますが、 クラスを継承し、これらのメソッドをオーバーライドする場合は、 それらは static として宣言する必要があります。

XML-RPC

XML-RPC 拡張モジュールは PECL に移動し、PHPの一部として配布されなくなりました。

Zip

ZipArchive::OPSYS_Z_CPM は削除されました(この名前は typo でした)。 ZipArchive::OPSYS_CPM を代わりに使って下さい。

Zlib

  • gzgetss 関数が削除されました。

  • zlib.output_compression は、Content-Type: image/* を自動的に無効にすることはなくなりました。

Windows の PHP Test Packs

テストランナーの名前が、run-test.php から run-tests.php に変更されました。 これは、php-src の名前に合わせるためです。