PHP 8.1 の新機能

in Vlog

(jp) =

<!–

–>

PHP 8.1 は 2021 年 11 月 25 日にリリースされました。現在、最新の PHP バージョンです。 この投稿では、すべての機能、パフォーマンスの向上、変更、および非推奨について 1 つずつ説明します。

# 新機能

すべてのリリースと同様に、PHP 8.1 にはいくつかの優れた新機能が追加されています。 このリストは 1 年で増えることに注意してください。

# 列挙型 RFC

Enum は PHP 8.1 で追加されます! それらが何に使用できるかわからない場合は、ここでそれらについて読むことができます。

列挙型を追加すると、PHP が大幅に改善されるため、PHP 8.1 で列挙型が導入されるのを非常に楽しみにしています。 それらがどのように見えるかを簡単にプレビューできるように、コードサンプルを次に示します。

enum Status 
  case Pending;
  case Active;
  case Archived;

そして、これはそれらがどのように使用されるかです:

class Post

    public function __construct(
        private Status $status = Status::Pending;
    ) 

    public function setStatus(Status $status): void
    
        
    


$post->setStatus(Status::Active);

この投稿では、列挙型の使用方法の詳細な分析を見つけることができます。


# 繊維 RFC

ファイバー (別名「グリーン スレッド」) は、並列処理を管理するための低レベルのメカニズムです。 アプリケーションでそれらを直接使用することはおそらくないでしょうが、Amphp や ReactPHP などのフレームワークはそれらを広範囲に使用します。

ファイバーを使用した簡単な例を次に示します。

$fiber = new Fiber(function (): void 
    $valueAfterResuming = Fiber::suspend('after suspending');
    
    
);
 
$valueAfterSuspending = $fiber->start();
 
$fiber->resume('after resuming');

ファイバーについて、ファイバーができることとできないことについてさらに読みたい場合は、この記事をお読みください。

# パフォーマンスの向上 広報

Dmitry Stogov は、opcache にいくつかの改良を加えました。彼はそれを「継承キャッシュ」と呼んでいます。 この機能により、PHP 7.4 でリンクされたクラスをプリロードできるように、クラス間のリンクをキャッシュできます。

Dmitry は、この変更のおかげでパフォーマンスが 5% から 8% 向上したと報告しています。これは、PHP 8.1 で注意すべき点です。


# 文字列キーによる配列のアンパック RFC

配列のアンパックは PHP 7.4 ですでに許可されていましたが、数値キーでしか機能しませんでした。 以前は文字列キーがサポートされていなかった理由は、配列の重複をマージする方法についてコンセンサスがなかったからです。 RFC は、次のセマンティクスに従ってこれをきれいに解決します。 array_merge:

$array1 = ["a" => 1];

$array2 = ["b" => 2];

$array = ["a" => 0, ...$array1, ...$array2];

var_dump($array); 

# new 初期化子で RFC

この RFC では、 new 属性引数やその他の場所だけでなく、デフォルトのパラメーターとしての関数定義のキーワード。

class MyController 
    public function __construct(
        private Logger $logger = new NullLogger(),
    ) 

この専用の投稿で、この機能のすべてを読むことができます。


# 読み取り専用プロパティ RFC

クラス プロパティは読み取り専用としてマークできます。つまり、一度だけ書き込むことができます。

class PostData 
    public function __construct(
        public readonly string $title,
        public readonly DateTimeImmutable $date,
    ) 

初期化後に読み取り専用プロパティを変更しようとすると、エラーが発生します。

$post = new Post('Title', );

$post->title = 'Other';

Error: Cannot modify readonly property Post::$title

読み取り専用プロパティについて詳しく知りたい場合は、私のフォローアップ投稿をお読みください。


# 第一級の呼び出し可能な構文 RFC

callable を呼び出して渡すことで、callable からクロージャーを作成できるようになりました。 ... その引数として:

function foo(int $a, int $b)   

$foo = foo(...);

$foo(a: 1, b: 2);

# 純粋交差タイプ RFC

PHP 8.0 の共用体型については既にご存じであり、交差型も同様の機能です。 共用体型では、入力が指定された型のいずれかである必要がありますが、交差型では、入力が指定されたすべての型である必要があります。 交差タイプは、多くのインターフェースを使用している場合に特に役立ちます。

function generateSlug(HasTitle&HasId $post) 
    return strtolower($post->getTitle()) . $post->getId();

このスタイルのプログラミングが好きなら、新しいインターフェースを作成する必要があります Sluggable そしてそれを実装します $post、交差点タイプはそのオーバーヘッドを取り除きます。


# 新しい never タイプ RFC

never type を使用して、関数が実際にプログラム フローを停止することを示すことができます。 これは、例外をスローするか、 exit または他の同様の機能。

function dd(mixed $input): never

    
    
    exit;

never とは異なり void その中で void それでもプログラムを続行できます。 これは目新しい機能のように思えるかもしれませんが、実際には静的アナライザーにとって非常に便利な機能です。


# 新しい array_is_list 関数 RFC

おそらくこれに対処しなければならなかったことがあります: 配列のキーがインデックス 0 から始まる番号順であるかどうかを判断します。 json_encode 配列を配列としてエンコードするかオブジェクトとしてエンコードするかを決定します。

PHP 8.1 では、配列がこれらのセマンティクスを持つリストであるかどうかを判断する組み込み関数が追加されています。

$list = ["a", "b", "c"];

array_is_list($list); 

$notAList = [1 => "a", 2 => "b", 3 => "c"];

array_is_list($notAList); 

$alsoNotAList = ["a" => "a", "b" => "b", "c" => "c"];

array_is_list($alsoNotAList); 

PHP 8.1 の開発に関する最新情報を入手しますか? ニュースレターを購読して、不定期に最新情報を受け取ります:


# 最終クラス定数 RFC

PHP のクラス定数は、継承時にオーバーライドできます。

class Foo

    public const X = "foo";

 
class Bar extends Foo

    public const X = "bar";

PHP 8.1 以降、そのような定数を次のようにマークできます。 final これを防ぐために:

class Foo

    final public const X = "foo";

 
class Bar extends Foo

    public const X = "bar";
    Fatal error: Bar::X cannot override final constant Foo::X

# 新しい fsync 関数 RFC

PHP 8.1 では、 fsyncfdatasync ディスクへのファイル変更の同期を強制し、戻る前にオペレーティング システムの書き込みバッファがフラッシュされていることを確認する関数。

$file = fopen("sample.txt", "w");

fwrite($file, "Some content");

if (fsync($file)) 
    echo "File has been successfully persisted to disk.";


fclose($file);

ディスク同期はファイル システム操作であるため、 fsync 関数はプレーン ファイル ストリームでのみ機能します。 ファイル以外のストリームを同期しようとすると、警告が表示されます。


# 明示的な 8 進整数リテラル表記 RFC

使えるようになりました 0o0O 8 進数を表します。 数字の前に 0 まだ同様に動作します。

016 === 0o16; 
016 === 0O16; 

# 重大な変更

PHP 8.1 はマイナー バージョンですが、技術的に重大な変更となる可能性のあるいくつかの変更と、廃止予定のものもあります。 それらについて1つずつ説明しましょう。


# 内部メソッドの戻り値の型 RFC

PHP 8.1 へのアップグレード時に、次の非推奨通知に遭遇する可能性があります。

Return type should either be compatible with IteratorAggregate::getIterator(): Traversable, 
or the #[ReturnTypeWillChange] attribute should be used to temporarily suppress the notice

使用中にこのエラーポップアップが表示される場合があります phpunit/phpunitsymfony/finder およびその他の一般的なオープン ソース パッケージ。 何が起こったかというと、内部関数が適切な戻り値の型を使用し始めているということです。 標準ライブラリからクラスを拡張している場合 ( IteratorAggregate)、それらの戻り値の型も追加する必要があります。

修正方法は簡単です。サード パーティのパッケージでエラーが発生した場合は、ベンダー コードを更新します (ほとんどの場合、最新のリリースで既に修正されています)。 コードでエラーが発生した場合は、次のいずれかを追加できます ReturnTypeWillChange PHP 9.0 までエラーを抑制します。 クラス拡張の例を次に示します。 DateTime:

class MyDateTime extends DateTime

    
    
    public function modify(string $modifier) 
     
        return false; 
    

または、単に戻り値の型を追加することもできます:

class MyDateTime extends DateTime

    public function modify(string $modifier): DateTime

# 制限 $GLOBALS 利用方法 RFC

やり方を少し変更 $GLOBALS を使用すると、すべてのアレイ操作のパフォーマンスに大きな影響を与えます。 Nikita は RFC で問題と解決策をうまく説明しています。 この変更は、一部のエッジ ケースがこれ以上処理できないことを意味します。 $GLOBALS. “サポートされなくなったのは、$GLOBALS への書き込み全体です。 以下はすべてコンパイル時エラーを生成します“:

$GLOBALS = [];
$GLOBALS += [];
$GLOBALS =& $x;
$x =& $GLOBALS;
unset($GLOBALS);

その上、通過 $GLOBALS 参照によって実行時エラーが発生します。

by_ref($GLOBALS); 

Nikita が Packagist の上位 2000 個のパッケージを分析したところ、この変更の影響を受けるケースは 23 個しか見つかりませんでした。 この — 技術的に破壊的な — 変更の影響は小さいと結論付けることができます。これが、内部が PHP 8.1 に追加することを決定した理由です。 コードのいたるところにパフォーマンスへのプラスの影響があることを考えると、ほとんどの人はこの変更で成功することを覚えておいてください。


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

これらの変更は、すべてのリソースを専用オブジェクトに変換するという長期的なビジョンの一部です。 詳細については、こちらをご覧ください。

Fileinfo 関数 finfo オブジェクト

のような機能 finfo_filefinfo_open リソースの受け入れと返却に使用されます。 PHP 8.1以降、それらはで動作します finfo オブジェクト。

を使用した IMAP 関数 IMAPConnection オブジェクト

fileinfo の変更と同様に、IMAP は次のように機能します。 imap_bodyimap_open リソースを操作しなくなりました


# 内部関数の null 非許容引数に null を渡すことを推奨しない RFC

この変更は簡単です: 内部関数は現在受け入れています null null 非許容の引数の場合、この RFC はその動作を非推奨にします。 たとえば、これは現在可能です。

str_contains("string", null);

PHP 8.1 では、これらの種類のエラーは非推奨の警告をスローし、PHP 9 では型エラーに変換されます。


# 自動活性化オン false RFC

RFC から:

PHP はネイティブで autovivification (falsey 値からの配列の自動作成) を許可します。 この機能は非常に便利で、特に変数が未定義の場合に多くの PHP プロジェクトで使用されています。 ただし、false 値と null 値から配列を作成できるという少し奇妙な点があります。

詳細は RFC ページで読むことができます。 要約すると、この動作は非推奨です。

$array = false;

$array[] = 2;

Automatic conversion of false to array is deprecated

#その他細かい変更

リリースごとに、言語には非常に小さな変更がたくさんあります。 それらはすべて、GitHub の UPGRADING ガイドと小規模な非推奨 RFC にリストされています。詳細をすべて知りたい場合は、必ずチェックしてください。

最も重要な変更点の概要は次のとおりです。

  • MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH 効果がなくなりました
  • MYSQLI_STORE_RESULT_COPY_DATA 効果がなくなりました
  • PDO::ATTR_STRINGIFY_FETCHES ブール値でも動作するようになりました
  • エミュレートされたプリペアド ステートメントを使用する場合、PDO MySQL および Sqlite の結果セットの整数と浮動小数点数は、文字列ではなくネイティブ PHP 型を使用して返されます。
  • のような機能 htmlspecialcharshtmlentities 今も逃げる ' デフォルトでは '; 不正な UTF-8 も、空の文字列になるのではなく、Unicode 文字に置き換えられます。
  • hashhash_filehash_init と呼ばれる追加の引数をそれらに追加します $options、デフォルト値は [] コードに影響を与えないように
  • の新しいサポート MurmurHash3xxHash

今のところは以上です。年内はこの記事を定期的に更新するので、最新情報を知りたい場合は購読してください。 PHP 8.1 に興奮していますか? 教えて ツイッター!

tpyoに気づきましたか? PR を送信して修正することができます。 このブログの最新情報を知りたい場合は、私をフォローしてください。 ツイッター または私のニュースレターを購読してください:

//platform.twitter.com/widgets.js

関連記事

前の投稿
Mac で Homebrew を使用して PHP 8.1 にアップグレードする
次の投稿
PHP のジェネリック (ビデオ) – Stitcher.io