ConFoo 2025

下位互換性のない変更点

PHP コア

配列でない値を配列スタイルでアクセスした場合

null, bool, int, float または resource 型を ($null["key"] のように) 配列としてアクセスしようとすると、警告が生成されるようになりました。

get_declared_classes() 関数

get_declared_classes() 関数は、まだインスタンス化されていない無名クラスを返さなくなりました。

fn キーワード

fn は、予約語になりました。特に、関数名やクラス名として使うことはできなくなりました。メソッド名やクラスの定数名の場合は使用できます。

ファイルの最後の <?php タグ

ファイルの最後の (改行が最後に付かない) <?php タグは、PHPタグの開始タグとして解釈されるようになりました。以前は、短い形式の開始タグ <? の後にリテラル php を続けたものとして解釈されるか、(short_open_tag=1 の場合は) 文法エラー になるか、(short_open_tag=0 の場合は) <?php というリテラルとして解釈されていました。

ストリームラッパー

ストリーム上で include/require を使う場合、streamWrapper::stream_set_option()STREAM_OPTION_READ_BUFFER オプション付きで呼び出されるようになります。カスタムのストリームラッパーの実装は 警告を回避するために streamWrapper::stream_set_option() を実装する必要があるかもしれません (不十分な実装に対しては常に false を返します)

シリアル化

シリアル化フォーマット o は削除されました。 PHP によって生成されなくなるので、手動で組まれた文字列のシリアル化を復元する場合のみ、壊れる場合があります。

パスワードアルゴリズムの定数

パスワードハッシュのアルゴリズムの識別子は、数値型ではなく、nullable な文字列型になりました。

  • PASSWORD_DEFAULT は int型の 1 でしたが、 string の '2y' になりました。 (PHP 7.4.0, 7.4.1, 7.4.2 では null でした)
  • PASSWORD_BCRYPT は int型の 1 でしたが、string の '2y' になりました。
  • PASSWORD_ARGON2I は int型の 2 でしたが、string の 'argon2i' になりました。
  • PASSWORD_ARGON2ID は int型の 3 でしたが、string の 'argon2id' になりました。

PASSWORD_DEFAULT, PASSWORD_BCRYPT, PASSWORD_ARGON2I, および PASSWORD_ARGON2ID 定数を正しく使っているアプリケーションは、正しく動作し続けるはずです。

htmlentities() 関数

htmlentities() 関数は 基本的なエンティティ置換だけをサポートしているエンコーディングで使われた場合、 (E_STRICT ではなく) E_NOTICE を発生させるようになりました。E_NOTICE が発生するのは、htmlspecialchars() の場合と同等です。

fread() および fwrite() 関数

fread()fwrite() 関数は、操作に失敗した場合に false を返すようになりました。以前は空文字列か 0 を返していました。EAGAIN/EWOULDBLOCK は、失敗と見做されません。

これらの関数は、読み取り専用のリソースに書き込もうとして失敗したような場合に E_NOTICE を発生させるようになりました。

BCMath

BCMath 関数は、"32foo" のような不完全な数値が渡された場合に警告を生成するようになりました。以前はそうした引数は0として解釈されていました。

CURL

CURLFile をシリアル化しようとすると、例外が発生するようになりました。以前は、シリアル化を復元しようとした場合のみ、例外が発生していました。

CURLPIPE_HTTP1 は非推奨になり、cURL 7.62.0 からサポートされなくなりました。

curl_version() 関数の $version 引数は推奨されません。デフォルトの CURLVERSION_NOW 以外の値が渡された場合、警告が生成され、渡された引数は無視されます。

日付と時刻

DateTimeDateTimeImmutable のインスタンスに対して var_dump() 類似の関数を呼び出しても、オブジェクトでアクセス可能なプロパティのみを表示するようになりました。

DateInterval オブジェクトを ( ==, < などを使って) 比較した場合、警告が出て常に false が返されるようになりました。以前は、プロパティがない場合、全ての DateInterval オブジェクトが等しいと見做されていました。

国際化関数

idn_to_ascii()idn_to_utf8() 関数のデフォルト値は、非推奨の INTL_IDNA_VARIANT_2003 ではなく INTL_IDNA_VARIANT_UTS46 となりました。

MySQLi

組み込みサーバーの機能は削除されました。少なくとも PHP 7.0 以降、この機能は壊れていました。

ドキュメントに書かれていない mysqli::$stat プロパティは削除され、mysqli::stat() に置き換えられました。

OpenSSL

openssl_random_pseudo_bytes() 関数は、エラーが発生した場合に例外をスローするようになりました。random_bytes() 関数も同じです。 特に、リクエストされたバイト数が0以下の場合には、 Error がスローされ、十分なランダム性が得られなかった場合は Exception が生成されます。 $crypto_strong の出力引数は、 例外がスローされなかった場合は常に true であることが保証されるので、明示的なチェックは不要です。

Regular Expressions (Perl互換)

PREG_UNMATCHED_AS_NULL モードが使われた場合、後に続くマッチしなかったキャプチャグループにも null (offset キャプチャが有効になっていた場合は [null, -1] になります) が設定されるようになりました。 これは、$matches のサイズが常に同じになることを意味します。

PDO

PDOPDOStatement のインスタンスをシリアル化しようとすると、PDOException ではなく Exception が生成されるようになりました。これは、シリアル化をサポートしていない他の内部的なクラスと一貫した挙動です。

ReflectionClassConstant, ReflectionMethod, ReflectionProperty のクラス定数の値が変更されました。

リフレクション

リフレクションオブジェクトをシリアル化しようとすると、例外を生成するようになりました。リフレクションオブジェクトのシリアル化はこれまでサポートされたことはなく、壊れたリフレクションオブジェクトを返していました。このバージョンから、明示的に禁止されました。

Standard PHP Library (SPL)

ArrayObject インスタンスに対して get_object_vars() 関数を呼ぶと、ArrayObject そのもの(またはそのサブクラス) のプロパティを常に返すようになりました。以前は、ArrayObject::STD_PROP_LIST フラグが指定されない限り、ラップされた 配列/オブジェクト の値を返していました。

他に影響を受ける操作として、以下が挙げられます:

  • ReflectionObject::getProperties()
  • reset(), current() など。 Iterator メソッドを代わりに使ってください。
  • オブジェクトのプロパティをリストとして扱うその他の操作も、影響を受ける可能性があります。 たとえば array_walk() 関数が挙げられます。

(array) キャストは影響を受けません。この操作は引き続き、ラップされた配列を返すか、ArrayObject のプロパティを返します。これは、ArrayObject::STD_PROP_LIST フラグが指定されたかどうかによって異なります。

SplPriorityQueue::setExtractFlags() は、0を渡された場合に例外をスローするようになりました。以前は、次の配列を展開する操作の際に回復可能な致命的なエラーを生成していました。

ArrayObject, ArrayIterator, SplDoublyLinkedList および SplObjectStorage は、Serializable に加えて、新たに __serialize()__unserialize() 機構をサポートしました。 これによって、古いPHPバージョンでシリアル化されたペイロードはまだ復元可能であることを意味しますが、PHP 7.4 で生成された新しいペイロードを、古いバージョンは理解しないことを意味します。

Tokenizer

token_get_all() 関数は、トークンストリームに穴を開けるのではなく、T_BAD_CHARACTER トークンを生成するようになりました。

外部から入力されるCookie

PHP 7.4.11 以降は、セキュリティ上の理由により、 外部から入力される Cookie の 名前 はurlデコードされなくなりました。

add a note

User Contributed Notes 1 note

up
18
happydog at kennel17
3 years ago
Re: "The o serialization format has been removed. As it is never produced by PHP, this may only break unserialization of manually crafted strings."

This little-o serialisation format was used by PHP3 but was never generated by PH PHP4 or above. The deserialization code still recognised it, though, for reasons of backwards-compatibility with PHP3.

However, based on a bit of investigation, it looks like this code has been broken for about 15 years, so although this is listed as a deprecation, in practice it wasn't.

See this Stack Overflow question for a really great answer, with a lot more detail about this: https://stackoverflow.com/questions/65289729/what-was-phps-o-serialization-format-for
To Top