search
LoginSignup
34

posted at

updated at

【PHP8.2】PHP8.2がリリースされたので新機能全部やる

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

strtolowerstrtoupperロケールの影響を受けなくなりました
具体的にはロケールが"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

ksortkrsortを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.

SensitiveParameterです。

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_quotedodbc_connection_string_should_quoteodbc_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.

strcmpstrncmpなどの文字列比較関数について、返り値が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_preparemysqli_stmt_bind_parammysqli_stmt_executemysqli_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::clearErrorZipArchive::getStreamNameZipArchive::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型などの追加でさらに隙が埋められました。
これで残る不足はいよいよ型エイリアスくらいでしょうか。

ところで公式のマイグレーションガイド、いつも日本語版が出るのは遅めなのですが、今回はリリース前から早々に日本語訳されていました。
誰の仕業かと思えばやはりこの人です。
いやーすごいね。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
34