PHP8.3 / PHP8.2 / PHP8.1 / PHP8.0
2022/12/08にPHP8.2.0がリリースされました。
大きな新機能については、PHP8.0以降公開されるようになったランディングページで見ることができます。
ここでは、概要だけではなくUPGRADINGに載っている変更点を全部見て回ることにします。
Backward Incompatible Changes
下位互換性のない変更点。
Date
DateTime::createFromImmutable() now has a tentative return type of static
DateTime::createFromImmutable()の返り値の型がstatic型になりました。
以前はDateTime型でした。
これはphpstanのバグへの対応です。
class CustomDateTimeImmutable extends DateTimeImmutable{
public function test(): self{
return CustomDateTimeImmutable::createFromInterface(new DateTime());
}
}
var_dump(get_class((new CustomDateTimeImmutable())->test())); // CustomDateTimeImmutable
CustomDateTimeImmutable上でcreateFromInterfaceを呼ぶと、実際はCustomDateTimeImmutableが返ってくるのにphpstanはDateTimeImmutableが返ってくると思い込んでエラーを出すよ、というバグです。
ところが調べてみたところPHPのシグネチャ的にはDateTimeImmutableが返ってくるのが正しいとなっていたので、PHP本体のバグだったとのことでした。
ややこしい。
DateTimeImmutable::createFromMutable() now has a tentative return type of static
DateTimeImmutable::createFromMutable()の返り値の型がstatic型になりました。
以前はDateTimeImmutable型でした。
上記のDateTime::createFromImmutable()
と全く同じ内容です。
ODBC
The ODBC extension now escapes the username and password
ODBC関数は、接続文字列とユーザー名/パスワードの両方を渡した場合に、ユーザー名/パスワードをエスケープするようになりました。
とあるけどこんなところにユーザ入力を渡すなって話だな。
phpMyAdminみたいなのが困るってことなのかな。
PDO_ODBC
The PDO_ODBC extension also escapes the username and password when a connection string is passed
PDOのODBCも同様にユーザー名/パスワードをエスケープするようになりました。
Standard
glob() returns empty array if all paths are restricted by open_basedir.
glob()は、パスがopen_basedirによって制限されている場合に空の配列を返すようになりました。
以前はエラーになっていましたが、これは存在しないパスを指定した場合などと異なる挙動でした。
strtolower() and strtoupper() are no longer locale-sensitive
strtolowerとstrtoupperはロケールの影響を受けなくなりました。
具体的にはロケールが"C"であるものとして扱われます。
また、stristr・stripos・strripos・lcfirst・ucfirst・ucwords・str_ireplace・array_change_key_caseの各関数、そしてソート関数のSORT_FLAG_CASEフラグも同じ動作になります。
str_split() returns an empty array for an empty string now
str_splitは空文字に空の配列を返すようになりました。
var_dump(str_split(''));
[] // PHP8.2
[0 => ''] // PHP8.1
mb_str_splitは以前から[]
であり、動作が異なっていました。
そこで動作を揃えたということです。
ksort() and krsort() do numeric string comparison under SORT_REGULAR
ksortとkrsortをSORT_REGULARでソートした場合、数値型文字列をPHP8のルールでソートするようになりました。
$a = ['a'=>1, 0=>1];
ksort($a);
var_dump($a);
[0=>1, 'a'=>1] // PHP8.2
['a'=>1, 0=>1] // PHP8.1
PHP8.0で比較演算子の挙動が変わったのですが、SORT_REGULARは何気にその変更に従っていませんでした。
今後は同じ挙動になります。
SPL
The following methods now enforce their signature
以下のメソッドがシグネチャを強制するようになりました。
SplFileInfo::_bad_state_ex()
SplFileObject::getCsvControl()
SplFileObject::fflush()
SplFileObject::ftell()
SplFileObject::fgetc()
SplFileObject::fpassthru()
って書いてあるんだけどどういう意味かわかりません。
SplFileObject::getCsvControl()とか引数ないし。
これまで返り値が守られないことがあったとか?
SplFileObject::hasChildren() now has a tentative return type of false
SplFileObject::hasChildren()の返り値の型がfalse型になりました。
以前はbool型でした。
SplFileObject::getChildren() now has a tentative return type of null
SplFileObject::getChildren()の返り値の型がnull型になりました。
以前は?RecursiveIterator型でした。
GlogIterator returns empty array if all paths are restricted by open_basedir
GlogIteratorは、パスがopen_basedirによって制限されている場合に空の配列を返すようになりました。
以前はエラーになっていましたが、これは存在しないパスを指定した場合などと異なる挙動でした。
New Features
新機能。
Core
Added the #[\SensitiveParameter] attribute to redact sensitive data in backtraces.
function test(
$foo = null,
#[\SensitiveParameter]
$bar = null,
) {
throw new \Exception('Error');
}
test('foo', 'bar');
PHP Fatal error: Uncaught Exception: Error in test.php
Stack trace: #0 test.php(11): test('foo', Object(SensitiveParameterValue))
アトリビュート#[\SensitiveParameter]
を設定した引数は、スタックトレースに出力されなくなります。
データベースパスワードなど、うっかり表示されてしまうと困るパラメータに指定しましょう。
It is now possible to use null and false as standalone types.
null型とfalse型が導入されました。
Added support for true type.
true型が導入されました。
function test(true $true, null $null) :false{
var_dump($null, $true);
return false;
}
test(true, null);
true型にはtrueしか渡すことができず、false型にはfalseしか渡すことができず、null型にはnullしか渡すことができません。
元々PHP8.0でUNION型を導入する過程において、主に歴史的理由からfalse疑似型とnull疑似型が導入されました。
これはUNION型の一部としてのみ使用可能で、単独では使えない型です。
その後交差型の対応などもあり、単独でも使えたほうが便利だろうということでPHP8.2でfalse型とnull型が正式に導入されました。
そうなるとtrue型がないのは片手落ちだろうということになってtrue型も対応となりました。
これらは引数としても使用可能ですが、ほとんど意味がありません。
返り値としての使用がメインとなるでしょう。
Added support for readonly classes
readonlyクラスです。
readonly class HOGE{
public int $a;
public function setA(int $a)
{
$this->a = $a;
}
}
$hoge = new HOGE();
$hoge->x = 1; // PHP Fatal error: Cannot create dynamic property HOGE::$x
$hoge->setA(1); // 1回目はOK
$hoge->setA(2); // PHP Fatal error: Cannot modify readonly property HOGE::$a
class FUGA extends HOGE{} // PHP Fatal error: Non-readonly class FUGA cannot extend readonly class HOGE
readonly class FUGA extends HOGE{} // こちらはOK
readonly
を指定したクラスには、動的プロパティ使用できず、プロパティには型が必須であり、さらに一度設定した値は変更できません。
できることが極めて限定されるかわりに、できることを限定した厳密な運用が可能となります。
Added support for Disjoint Normal Form (DNF) types
型合成です。
interface A{}
interface B{}
class C{}
function hoge((Traversable & Countable)|string $param): (A&B)|C{
return new C();
}
hoge('a'); // OK
hoge(new ArrayIterator()); // OK
hoge(new EmptyIterator()); // Fatal error: hoge(): Argument #1 ($param) must be of type (Traversable&Countable)|string, EmptyIterator given
A型かつB型、もしくはC型、みたいな複雑な型合成ができるようになります。
型に無頓着なPHPという評価は過去の遺物であり、今のPHPは下手な言語よりよっぽどかちかちに型を固めることが可能になっています。
Added error_log_mode ini setting that allows setting of permissions for error log file
ini設定error_log_modeが追加されました。
error_log_mode=0o644
とするとエラーログファイルのパーミッションが0644になります。
Added support for fetching properties of enums in constant expressions
constにENUMの->
が使えるようになります。
enum E: string {
case Foo = 'foo';
}
const C = E::Foo->name;
var_dump(C); // Foo
元々const I = DateTimeInterface::ATOM
とか書けていたので、それと同じような扱いになります。
Added support for defining constants in traits
トレイトに定数が書けるようになります。
trait T {
public const CONSTANT = 42;
}
どうしてこれまで使えなかったかというと、実装したとき特に考えてなかったからだそうです。
Curl
Added CURLINFO_EFFECTIVE_METHOD option and returning the effective HTTP method in curl_getinfo() return value.
定数CURLINFO_EFFECTIVE_METHODが追加されました。
これはCurlの同名の定数のラッパーです。
curl_getinfo()のオプションとして使用可能で、有効なHTTPリクエストメソッドを取得できます。
$ch = curl_init();
var_dump(curl_getinfo($ch, CURLINFO_EFFECTIVE_METHOD)); // GET
curl_setopt($ch, CURLOPT_POST, true);
var_dump(curl_getinfo($ch, CURLINFO_EFFECTIVE_METHOD)); // GET ←?
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HOGE');
var_dump(curl_getinfo($ch, CURLINFO_EFFECTIVE_METHOD)); // HOGE
Exposed multiple new constants from libcurl 7.62 to 7.80
同梱のlibcurlがバージョン7.62から7.80になったことに伴い、その間に実装されたcurl定数が追加されました。
全部で80個くらいあるので詳細は省略します。
Added new function curl_upkeep() to perform any connection upkeep checks
関数curl_upkeep()が追加されました。
長時間接続し続けたいときに、ちょっとだけデータを送って接続をキープする関数です。
DBA
The LMDB Driver now accepts the DBA_LMDB_USE_SUB_DIR or DBA_LMDB_NO_SUB_DIR flags
LMDBドライバが、DBA_LMDB_USE_SUB_DIRおよびDBA_LMDB_NO_SUB_DIRフラグを受け付けるようになりました。
ファイルを作るときにサブディレクトリを有効にするしないの設定みたいです。
そもそもLightning Memory-Mapped Databaseなるものが初耳だったよ。
OCI8
Added an oci8.prefetch_lob_size directive and oci_set_prefetch_lob() function
ini設定oci8.prefetch_lob_size
と、関数oci_set_prefetch_lobが追加されました。
Oracle 12.2以降で使用可能で、LOBへのクエリのパフォーマンスを調整することができます。
ということらしいのですがどういう意味だかさっぱりだ。
OpenSSL
Added AEAD support for chacha20-poly1305 algorithm
認証付き暗号アルゴリズム、chacha20-poly1305がサポートされました。
なるほど、さっぱりわからん。
ODBC
Added odbc_connection_string_is_quoted, odbc_connection_string_should_quote, and odbc_connection_string_quote.
関数odbc_connection_string_is_quoted、odbc_connection_string_should_quote、odbc_connection_string_quoteが追加されました。
これは主にODBCとPDO_ODBCが裏で使用するものですが、うまく使えばユニットテストに便利なので公開しているそうです。
でも具体的に何なのかは不明。
PCRE
Added support for the "n" (NO_AUTO_CAPTURE) modifier
PCRE正規表現のパターン修正子n
が追加されました。
これは2017年に導入されたNO_AUTO_CAPTUREに対応したものです。
// フラグnが追加された
preg_match('/(foo)(bar)(?<capture1>baz)/n', 'foobarbaz', $matches);
var_dump($matches);
/*
array(3) {
[0]=>
string(9) "foobarbaz"
["capture1"]=>
string(3) "baz"
[1]=>
string(3) "baz"
}
*/
// 既存の挙動
preg_match('/(foo)(bar)(?<capture1>baz)/n', 'foobarbaz', $matches);
var_dump($matches);
/*
array(5) {
[0]=>
string(9) "foobarbaz"
[1]=>
string(3) "foo"
[2]=>
string(3) "bar"
["capture1"]=>
string(3) "baz"
[3]=>
string(3) "baz"
}
*/
修正子n
を指定すると、名前付きキャプチャグループ(?<xxxx>)
だけがキャプチャ対象になり、ただの()
はキャプチャグループとみなされなくなります。
修正子n
を指定しない場合は、これまでどおり通常の()
と名前付き(?<xxxx>)
両方ともがキャプチャされます。
括弧を検索したい場合などに便利なフラグだと思います。
Random
New extension that organizes and consolidates existing implementations related to random number generators
乱数の大幅改善です。
これまで様々な問題のあったPHPの乱数を一新し、安全性と使い勝手を劇的に改善します。
// 乱数エンジン
$engine = new \Random\Engine\Secure();
// 乱数生成器
$randomizer = new \Random\Randomizer($engine);
var_dump(
$randomizer->getInt(0, 100), // random_int
$randomizer->shuffleArray([1, 2, 3]), // shuffle
$randomizer->getBytes(10), // random_bytes
$randomizer->shuffleBytes('abcde'), // str_shuffle
$randomizer->pickArrayKeys([1, 2, 3], 1), // array_rand
);
また、状態をクラスに閉じ込めることでグローバルな乱数状態の影響を受けることがなくなります。
さらに乱数生成エンジンを差し替えることもできるようになります。
Changes in SAPI modules
SAPIの変更はありません。
Deprecated Functionality
非推奨になった機能。
Core
Creation of dynamic properties is deprecated
動的プロパティは非推奨になりました。
class HOGE{
public function __construct()
{
$this->foo = 1;
}
}
new HOGE(); // PHP Deprecated: Creation of dynamic property HOGE::$foo is deprecated
プロパティは定義しなければなりません。
PHP8.2でDeprecated、PHP9でエラーになります。
正しい対応はクラスのプロパティにprivate $foo = null
と書くことですが、可変変数を使っているなどで対応が困難な場合はアトリビュート#[AllowDynamicProperties]
を使うことで当面エラーを回避することができます。
Mbstring
Use of QPrint, Base64, Uuencode, and HTML-ENTITIES 'text encodings' is deprecated
mbstringにおいて、QPrint・Base64・Uuencode・HTML-ENTITIESのテキストエンコーディングが非推奨になります。
mb_convert_encoding('あいうえお', 'Base64', 'UTF-8'); // PHP Deprecated: mb_convert_encoding(): Handling Base64 via mbstring is deprecated; use base64_encode/base64_decode instead
これらはUNICODEエンコーディングではなくバイト列のエンコーディングだからとかなんとからしいのですがよくわかりません。
SPL
The SplFileInfo::_bad_state_ex() internal method has been deprecated
内部関数SplFileInfo::_bad_state_ex()
が非推奨になりました。
表には出ていない関数なので、ユーザには特に影響ないでしょう。
Standard
utf8_encode() and utf8_decode() have been deprecated
utf8_encodeおよびutf8_decodeが非推奨になりました。
この関数は予想に反して「ISO-8859-1をUTF-8に変換する」という用途が狭すぎる関数です。
かわりにmb_convert_encodingを使いましょう。
Changed Functions
動作に変更のある関数。
Core
str*cmp, str*pos, substr_compare functions, using binary safe string comparison now return -1, 0 and 1.
strcmpやstrncmpなどの文字列比較関数について、返り値が1か-1か0になりました。
これまではプラス値とマイナス値を返す場合、その値は1になるとは限りませんでした。
var_dump(strcmp('a', 'z'));
// PHP8.1まで-25
// PHP8.2から-1
DBA
dba_open() and dba_popen() now have the following enforced function signature
dba_openに引数$flags
が追加されました。
dba_open(
string $path,
string $mode,
?string $handler = null,
int $permission = 0644,
int $map_size = 0,
?int $flags = null
): resource|false
dba_fetch()'s optional skip argument is now at the end in line
dba_fetchの引数が変更になりました。
// PHP8.2以降
dba_fetch(string|array $key, resource $dba, int $skip = 0): string|false
// PHP8.1まで
dba_fetch(string $key, int $skip, resource $dba): string
順番入れ替えるのやめようよ。
Random
random_bytes() and random_int() now throw \Random\RandomException on CSPRNG failure.
random_bytesおよびrandom_intが、乱数生成器が手に入らないときに\Random\RandomException
をスローするようになりました。
これまではただの\Exception
でした。
これを発生させるにはCNG APIとかgetrandom(2)とかを削除しないといけないという、むしろ発生させることが難しいエラーです。
SPL
The $iterator parameter of iterator_to_array() and iterator_count() is widened to iterable from Iterator
iterator_to_arrayおよびiterator_countにおいて、引数$iterator
の型がIterator
からiterable
になりました。
iterator_to_array([1, 2, 3]);
// PHP8.2以降 OK
// PHP8.1まで Fatal error: iterator_to_array(): Argument #1 ($iterator) must be of type Traversable, array given
要するに配列を渡してもエラーが起こらなくなりました。
これはそもそも今まで渡せなかったのがおかしいので、妥当な修正でしょう。
XML
xml_parser_set_option() now actually returns false when attempting to set a negative tag start
xml_parser_set_optionの第二引数にXML_OPTION_SKIP_TAGSTART、第三引数に負の値を渡したときの返り値がfalseになりました。
$parser = xml_parser_create();
var_dump(xml_parser_set_option( $parser, \XML_OPTION_SKIP_TAGSTART, -1));
// PHP8.2以降 false
// PHP8.1まで true
これまではtrueを返す、でも不正な値なので設定は失敗、という状態になっていました。
New Functions
新しい関数。
Curl
curl_upkeep
関数curl_upkeep()が追加されました。
少しだけデータを送って、接続を維持する関数です。
mysqli_execute_query
関数mysqli_execute_query()が追加されました。
mysqli_prepareとmysqli_stmt_bind_paramとmysqli_stmt_executeとmysqli_stmt_get_resultをひとまとめにした関数です。
$mysqli = new mysqli();
$query = 'SELECT Name, Population, Continent FROM Country WHERE Continent=? ORDER BY Name LIMIT 1';
// PHP8.2以降
$result = $mysqli->execute_query($query, ['Europe']);
// PHP8.1まで
$stmt = $mysqli->prepare($query);
$stmt->bind_param('s', 'Europe');
$stmt->execute();
$result = $stmt->get_result();
ちょっとしたSQLが非常に書きやすくなりますね。
OpenSSL
openssl_cipher_key_length
関数openssl_cipher_key_length()が追加されました。
暗号鍵の長さを取得します。
$methods = openssl_get_cipher_methods();
foreach($methods as $method){
$length = openssl_cipher_key_length($method);
printf('Method:%1$s KeyLength:%2$d'."\n", $method, $length);
}
/*
こんなかんじになる
Method:aes-128-cbc KeyLength:16
Method:aes-128-cbc-cts KeyLength:0
Method:aes-128-cbc-hmac-sha1 KeyLength:16
Method:aes-128-cbc-hmac-sha256 KeyLength:16
Method:aes-128-ccm KeyLength:16
Method:aes-192-ccm KeyLength:24
Method:aes-256-ccm KeyLength:32
*/
どんなときに使うのかはよくわかりません。
Reflection
ReflectionFunction::isAnonymous()
ReflectionFunction::isAnonymousが追加されました。
無名関数かどうかを調べることができます。
$f1 = function(){};
function f2(){};
var_dump(
(new ReflectionFunction($f1))->isAnonymous(), // true
(new ReflectionFunction('f2'))->isAnonymous(), // false
);
ReflectionMethod::hasPrototype()
ReflectionMethod::hasPrototypeが追加されました。
メソッドがプロトタイプを持つか調べることができます。
class C1{
function M2(){}
}
class C2 extends C1{
function M2(){}
}
class C3 extends C1{
function M3(){}
}
var_dump(
(new ReflectionMethod('C2', 'M2'))->hasPrototype(), // true
(new ReflectionMethod('C3', 'M3'))->hasPrototype(), // false
);
プロトタイプって何かというと要するにparent::
のことです。
何故かスコープ定義演算子とか継承のあたりではプロトタイプって言葉を使ってないのでわかりにくいですね。
Sodium
sodium_crypto_stream_xchacha20_xor_ic()
sodium_crypto_stream_xchacha20_xor_icが追加されました。
var_dump(sodium_crypto_stream_xchacha20_xor_ic('a', random_bytes(24), 1, 'key'));
// PHP Fatal error: Uncaught SodiumException: sodium_crypto_stream_xchacha20_xor_ic(): Argument #3 ($counter) must be SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES bytes long
第三引数$counter
をSODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES桁のintで渡せと言われたんだけど、SODIUM_CRYPTO_STREAM_XCHACHA20_KEYBYTES=32なので32桁のintが必要となってこれ無理なんだけどどういうことだろう。
Standard
The peak memory usage can now be reset to the current usage thanks to memory_reset_peak_usage()
memory_reset_peak_usageが追加されました。
memory_get_peak_usageの値をリセットします。
/* なんかメモリ使う処理1 */
var_dump(memory_get_peak_usage()); // 最大メモリ使用量を確認
memory_reset_peak_usage(); // リセット
/* なんかメモリ使う処理2 */
var_dump(memory_get_peak_usage()); // 最大メモリ使用量を確認
メモリ使用量を調査するベンチマークなどは、これまで処理ごとに別ファイルにしなければならなかったのですが、この関数が入ったことにより1ファイルで書けるようになりました。
ini_parse_quantity
ini_parse_quantityが追加されました。
var_dump(ini_parse_quantity('1G')); // 1073741824
ini設定から、post_max_size = 8M
みたいに書かれた値をパースします。
はい、それだけです。
対応している値はK、M、Gだけであり、TとかQとかは未対応です。
ini_getの例にある関数return_bytesと実質同じだと思われます。
XML
libxml_get_external_entity_loader
libxml_get_external_entity_loaderが追加されました。
libxml_set_external_entity_loaderで登録したエンティティローダーを取得します。
$loader = function(string $public_id, string $system_id, array $context):string{
return $public_id.$system_id;
};
libxml_set_external_entity_loader($loader);
$loader2 = libxml_get_external_entity_loader();
var_dump($loader2('a', 'b', [])); // ab
どういうときに使うのかは、よくわかりません。
New Classes and Interfaces
新しいクラスやインターフェイスはありません。
Removed Extensions and SAPIs
削除されたエクステンションはありません。
Other Changes to Extensions
Date
DatePeriod properties are now properly declared
DatePeriodのプロパティが適切に宣言されました。
とだけしか書かれてないので何のことだかよくわかりません。
Intl
instances are no longer serializable
以下のIntl関連クラスがシリアライズできなくなりました。
これまではserialize自体は通せていましたが、元に戻せないものができていたりと不具合がありました。
・IntlBreakIterator
・IntlRuleBasedBreakIterator
・IntlCodePointBreakIterator
・IntlPartsIterator
・IntlCalendar
・Collator
・IntlIterator
・UConverter
・IntlDateFormatter
・IntlDatePatternGenerator
・MessageFormatter
・ResourceBundle
・Spoofchecker
・IntlTimeZone
・Transliterator
mysqli
The support for libmysql has been removed
MySQLドライバlibmysqlが削除されました。
あらゆる面でmysqlndのほうが有利なので、今後はそちらに統一されます。
The reconnect property of mysqli_driver has been removed
mysqli_driver::reconnectが削除されました。
同時にini設定mysqli.reconnectも削除されました。
これらは元々libmysqlにしか存在しない機能で、mysqlndはこれを無視していました。
The constant MYSQLI_IS_MARIADB has been deprecated
定数MYSQLI_IS_MARIADBが削除されました。
mysqliモジュールがMariaDBで構築されているかを示すフラグらしいのですが、これはlibmysqlにしか存在しないらしいので一緒に削除されました。
OCI8
The minimum Oracle Client library version required is now 11.2
Oracleクライアントの最低バージョンが11.2になりました。
11.2は2009年9月リリースリリースらしいので、これより昔のバージョンとか流石に切っていいでしょう。
PCRE
NUL characters (\0) in pattern strings are now supported
preg_match等に検索文字列としてヌルバイトが使えるようになりました。
preg_match("/a".chr(0)."bc/", 'abc');
// PHP8.2以降 エラー出ない
// PHP8.1まで Warning: preg_match(): Null byte in regex
そんなもの検索してどうするんだって気がしないでもない。
Session
Trying to change the SameSite cookie now fail and emit a warning
セッションが既に有効になったあと、もしくは既にレスポンスが出力された後で、samesite要素を変更しようとすると失敗します。
これは他のセッション要素と同じ動作です。
SQLite3
sqlite3.defensive is now PHP_INI_USER
ini設定sqlite3.defensiveがPHP_INI_USERになりました。
これまではPHP_INI_SYSTEMでした。
Standard
getimagesize() now reports the actual image dimensions, bits and channels of AVIF images.
getimagesizeが、AVIFフォーマットの画像について正しいサイズやビット数を返すようになりました。
これまではサイズは0×0となり、ビット数などは返ってきませんでした。
var_dump(getimagesize('test.avif')); // 適当なavif画像
// PHP8.2以降
array(7) {
[0]=>
int(960)
[1]=>
int(540)
[2]=>
int(19)
[3]=>
string(24) "width="960" height="540""
["bits"]=>
int(8)
["channels"]=>
int(3)
["mime"]=>
string(10) "image/avif"
}
// PHP8.1まで
array(5) {
[0]=>
int(0)
[1]=>
int(0)
[2]=>
int(19)
[3]=>
string(20) "width="0" height="0""
["mime"]=>
string(10) "image/avif"
}
Tidy
tidy properties are now properly declared
tidyのプロパティが適切に宣言されました。
tidyNodeのプロパティが適切にreadonlyで宣言されました。
とだけしか書かれてないので何のことだかよくわかりません。
Zip
extension updated to 1.20.0
Zipエクステンションのバージョンが1.20.0になりました。
バージョンアップに伴い、ZipArchive::clearError、ZipArchive::getStreamName、ZipArchive::getStreamIndexが追加されました。
New Global Constants
追加されたグローバル定数。
基本的には、PHPが使用しているドライバで追加された定数をそのままインポートしているだけのようです。
COM_DOTNET
DISP_E_PARAMNOTFOUND
LOCALE_NEUTRAL
Curl
CURLALTSVC_H1 (libcurl >= 7.64.1)
CURLALTSVC_H2 (libcurl >= 7.64.1)
CURLALTSVC_H3 (libcurl >= 7.64.1)
CURLALTSVC_READONLYFILE (libcurl >= 7.64.1)
CURLAUTH_AWS_SIGV4 (libcurl >= 7.75.0)
CURLE_PROXY (libcurl >= 7.73.0)
CURLFTPMETHOD_DEFAULT
CURLHSTS_ENABLE (libcurl >= 7.74.0)
CURLHSTS_READONLYFILE (libcurl >= 7.74.0)
CURLINFO_PROXY_ERROR (libcurl >= 7.73.0)
CURLINFO_REFERER (libcurl >= 7.76.0)
CURLINFO_RETRY_AFTER (libcurl >= 7.66.0)
CURLMOPT_MAX_CONCURRENT_STREAMS (libcurl >= 7.67.0)
CURLOPT_ALTSVC_CTRL (libcurl >= 7.64.1)
CURLOPT_ALTSVC (libcurl >= 7.64.1)
CURLOPT_AWS_SIGV4 (libcurl >= 7.75.0)
CURLOPT_CAINFO_BLOB (libcurl >= 7.77.0)
CURLOPT_DOH_SSL_VERIFYHOST (libcurl >= 7.76.0)
CURLOPT_DOH_SSL_VERIFYPEER (libcurl >= 7.76.0)
CURLOPT_DOH_SSL_VERIFYSTATUS (libcurl >= 7.76.0)
CURLOPT_HSTS_CTRL (libcurl >= 7.74.0)
CURLOPT_HSTS (libcurl >= 7.74.0)
CURLOPT_MAIL_RCPT_ALLLOWFAILS (libcurl >= 7.69.0)
CURLOPT_MAXAGE_CONN (libcurl >= 7.65.0)
CURLOPT_MAXFILESIZE_LARGE
CURLOPT_MAXLIFETIME_CONN (libcurl >= 7.80.0)
CURLOPT_PROXY_CAINFO_BLOB (libcurl >= 7.77.0)
CURLOPT_SASL_AUTHZID (libcurl >= 7.66.0)
CURLOPT_SSH_HOST_PUBLIC_KEY_SHA256 (libcurl >= 7.80.0)
CURLOPT_SSL_EC_CURVES (libcurl >= 7.73.0)
CURLOPT_UPKEEP_INTERVAL_MS (libcurl >= 7.62.0)
CURLOPT_UPLOAD_BUFFERSIZE (libcurl >= 7.62.0)
CURLOPT_XFERINFOFUNCTION (libcurl >= 7.32.0)
CURLPROTO_MQTT (libcurl >= 7.71.0)
CURLPX_BAD_ADDRESS_TYPE (libcurl >= 7.73.0)
CURLPX_BAD_VERSION (libcurl >= 7.73.0)
CURLPX_CLOSED (libcurl >= 7.73.0)
CURLPX_GSSAPI (libcurl >= 7.73.0)
CURLPX_GSSAPI_PERMSG (libcurl >= 7.73.0)
CURLPX_GSSAPI_PROTECTION (libcurl >= 7.73.0)
CURLPX_IDENTD_DIFFER (libcurl >= 7.73.0)
CURLPX_IDENTD (libcurl >= 7.73.0)
CURLPX_LONG_HOSTNAME (libcurl >= 7.73.0)
CURLPX_LONG_PASSWD (libcurl >= 7.73.0)
CURLPX_LONG_USER (libcurl >= 7.73.0)
CURLPX_NO_AUTH (libcurl >= 7.73.0)
CURLPX_OK (libcurl >= 7.73.0)
CURLPX_RECV_ADDRESS (libcurl >= 7.73.0)
CURLPX_RECV_AUTH (libcurl >= 7.73.0)
CURLPX_RECV_CONNECT (libcurl >= 7.73.0)
CURLPX_RECV_REQACK (libcurl >= 7.73.0)
CURLPX_REPLY_ADDRESS_TYPE_NOT_SUPPORTED (libcurl >= 7.73.0)
CURLPX_REPLY_COMMAND_NOT_SUPPORTED (libcurl >= 7.73.0)
CURLPX_REPLY_CONNECTION_REFUSED (libcurl >= 7.73.0)
CURLPX_REPLY_GENERAL_SERVER_FAILURE (libcurl >= 7.73.0)
CURLPX_REPLY_HOST_UNREACHABLE (libcurl >= 7.73.0)
CURLPX_REPLY_NETWORK_UNREACHABLE (libcurl >= 7.73.0)
CURLPX_REPLY_NOT_ALLOWED (libcurl >= 7.73.0)
CURLPX_REPLY_TTL_EXPIRED (libcurl >= 7.73.0)
CURLPX_REPLY_UNASSIGNED (libcurl >= 7.73.0)
CURLPX_REQUEST_FAILED (libcurl >= 7.73.0)
CURLPX_RESOLVE_HOST (libcurl >= 7.73.0)
CURLPX_SEND_AUTH (libcurl >= 7.73.0)
CURLPX_SEND_CONNECT (libcurl >= 7.73.0)
CURLPX_SEND_REQUEST (libcurl >= 7.73.0)
CURLPX_UNKNOWN_FAIL (libcurl >= 7.73.0)
CURLPX_UNKNOWN_MODE (libcurl >= 7.73.0)
CURLPX_USER_REJECTED (libcurl >= 7.73.0)
CURLSSLOPT_AUTO_CLIENT_CERT (libcurl >= 7.77.0)
CURLSSLOPT_NATIVE_CA (libcurl >= 7.71.0)
CURLSSLOPT_NO_PARTIALCHAIN (libcurl >= 7.68.0)
CURLSSLOPT_REVOKE_BEST_EFFORT (libcurl >= 7.70.0)
CURL_VERSION_GSASL (libcurl >= 7.76.0)
CURL_VERSION_HSTS (libcurl >= 7.74.0)
CURL_VERSION_HTTP3 (libcurl >= 7.66.0)
CURL_VERSION_UNICODE (libcurl >= 7.72.0)
CURL_VERSION_ZSTD (libcurl >= 7.72.0)
Filter
FILTER_FLAG_GLOBAL_RANGE
Sockets
SO_INCOMING_CPU
SO_MEMINFO
SO_RTABLE (OpenBSD)
TCP_KEEPALIVE (MacOS)
TCP_KEEPCNT (Linux, others)
TCP_KEEPIDLE (Linux, others)
TCP_KEEPINTVL (Linux, others)
TCP_NOTSENT_LOWAT
LOCAL_CREDS_PERSISTENT (FreeBSD)
SCM_CREDS2 (FreeBSD)
LOCAL_CREDS (NetBSD)
SO_BPF_EXTENSIONS
SO_SETFIB
TCP_CONGESTION (Linux, FreeBSD)
SO_ZEROCOPY (Linux)
MSG_ZEROCOPY (Linux)
Changes to INI File Handling
iniファイルの取り扱いに関する変更点。
Support for binary and octal number
iniファイルで2進数0b
と8進数0o
の接頭辞がサポートされました。
これまでは16進数0x
と、0777
のように0o
ではない形の8進数だけがサポートされていました。
Parsing of some ill-formatted values will now trigger a warning
正しくないフォーマットの値が、警告を発生させるようになりました。
これまではエラーが出ませんでした。
値の解釈そのものは、互換性のためそのまま維持されます。
以下の項目で発生する可能性があります。
bcmath.scale
com.code_page
default_socket_timeout
fiber.stack_size
hard_timeout
intl.error_level
ldap.max_links
max_input_nesting_level
max_input_vars
mbstring.regex_retry_limit
mbstring.regex_stack_limit
mysqli.allow_local_infile
mysqli.allow_persistent
mysqli.default_port
mysqli.max_links
mysqli.max_persistent
mysqli.reconnect
mysqli.rollback_on_cached_plink
mysqlnd.log_mask
mysqlnd.mempool_default_size
mysqlnd.net_read_buffer_size
mysqlnd.net_read_timeout
oci8.default_prefetch
oci8.max_persistent
oci8.persistent_timeout
oci8.ping_interval
oci8.prefetch_lob_size
oci8.privileged_connect
oci8.statement_cache_size
odbc.allow_persistent
odbc.check_persistent
odbc.defaultbinmode
odbc.default_cursortype
odbc.defaultlrl
odbc.max_links
odbc.max_persistent
opcache.consistency_checks
opcache.file_update_protection
opcache.force_restart_timeout
opcache.interned_strings_buffer
opcache.jit_bisect_limit
opcache.jit_blacklist_root_trace
opcache.jit_blacklist_side_trace
opcache.jit_debug
opcache.jit_hot_func
opcache.jit_hot_loop
opcache.jit_hot_return
opcache.jit_hot_side_exit
opcache.jit_max_exit_counters
opcache.jit_max_loop_unrolls
opcache.jit_max_polymorphic_calls
opcache.jit_max_recursive_calls
opcache.jit_max_recursive_returns
opcache.jit_max_root_traces
opcache.jit_max_side_traces
opcache.log_verbosity_level
opcache.max_file_size
opcache.opt_debug_level
opcache.optimization_level
opcache.revalidate_freq
output_buffering
pcre.backtrack_limit
pcre.recursion_limit
pgsql.max_links
pgsql.max_persistent
post_max_size
realpath_cache_size
realpath_cache_ttl
session.cache_expire
session.cookie_lifetime
session.gc_divisor
session.gc_maxlifetime
session.gc_probability
soap.wsdl_cache_limit
soap.wsdl_cache_ttl
unserialize_max_depth
upload_max_filesize
user_ini.cache_ttl
xmlrpc_error_number
zend.assertions
zlib.output_compression_level
Windows Support
Windowsのサポート。
Core
Windows specific error messages are no longer localized
Windows固有のエラーはローカライズされなくなり、常に英語で表示されるようになりました。
といっても元々ほぼ英語だったのであんまり関係なさそう。
Preliminary and highly experimental support for building on ARM64 has been added
ARM64の予備実験的サポートが追加されました。
preliminaryかつexperimentalなので、まだ実用はできないでしょう。
OCI8
Since building against Oracle Client 10g is no longer supported
Oracle 10gはサポートされなくなり、設定オプション--with-oci8
は削除されました。
設定オプション--with-oci8-11g
・--with-oci8-12c
・--with-oci8-19
はまだサポートされています。
なんで19cじゃないんだろう?
Zip
The Zip extension upgraded to version 1.21.0
Zipエクステンションのバージョンが1.20.0になりました。
The Zip extension is now built as shared library (DLL) by default
ZipエクステンションのDLLがデフォルトで同梱されるようになりました。
Other Changes
その他の変更点。
CLI
The STDOUT, STDERR and STDIN are no longer closed on resource destruction which is mostly when the CLI finishes
リソースを破棄してもSTDOUT、STDERR、STDINが閉じなくなりました。
とあるのですが、具体的にどのようなときに起こるのかよくわかりませんでした。
なおfclose等で明白に破棄すると、PHP8.2でも消えます。
var_dump(STDIN); // resource(1) of type (stream)
fclose(STDIN);
var_dump(STDIN); // resource(1) of type (Unknown)
Core
iterable type is now a built-in compile time alias for array|Traversable
iterable
型はarray|Traversable
型のエイリアスであるため、エラーメッセージなどにiterable
ではなくarray|Traversable
を使うようになりました。
$f = function(iterable $p){};
$f(1);
// PHP8.2以降 Fatal error: {closure}(): Argument #1 ($p) must be of type Traversable|array, int given
// PHP8.1まで Fatal error: {closure}(): Argument #1 ($p) must be of type iterable, int given
感想
細かな使い勝手の向上などがメインであり、大きな新機能といえるのは乱数改善くらいでしょうか。
それ以外には動的プロパティの廃止など、PHP9に向けての前準備といったものが見当たります。
PHP8.0のJITや、PHP8.1の型要素の大幅拡充などに比べると、目玉機能というようなものがなく、その点では少々物足りないところがありますね。
なんといっても最大の変更点は、動的プロパティの非推奨です。
これによって、どこから生えたかわからない謎プロパティみたいなのを撃滅することが可能になり、PHPのつらいところをひとつ減らすことができます。
ただ古くから継ぎ足して使われているようなソースでは、ほぼ間違いなく動的プロパティが使われていると思うので、この変更によって動かなくなってしまう可能性があります。
PHP8.2ではまだ警告が出るだけですが、PHP9で動かなくなることが決定しているので、この機会に見直してみるとよいでしょう。
またPHP8.0/8.1で大幅拡充された型システムについては、falseやtrue型などの追加でさらに隙が埋められました。
これで残る不足はいよいよ型エイリアスくらいでしょうか。
ところで公式のマイグレーションガイド、いつも日本語版が出るのは遅めなのですが、今回はリリース前から早々に日本語訳されていました。
誰の仕業かと思えばやはりこの人です。
いやーすごいね。