Open hysryt opened 2 years ago
https://www.php.net/manual/ja/language.enumerations.php
enum Status
{
case Draft;
case Published;
case Archived;
}
function acceptStatus(Status $status) {...}
PHPでは列挙型はクラスであり、定義されるcaseはそれぞれインスタンス。
$a = Suit::Spades;
$b = Suit::Spades;
$a === $b; // true
$a instanceof Suit; // true
列挙型はメソッドを持つことができる。 スタティックメソッドを持つこともできる。 インターフェースを実装することもできる。 定数を持つこともできる。 トレイトを使う(use)することもできるが、トレイトがプロパティを持たない場合のみ。
コンストラクタやデストラクタは無い。
列挙型を継承することはできない。
プロパティは持てない。
clone
できない。
列挙型は内部的に UnitEnum
インターフェースを実装している。
各caseがスカラー値を持つ列挙型
enum Suit: string
{
case Hearts = 'H';
case Diamonds = 'D';
case Clubs = 'C';
case Spades = 'S';
}
Backed Enum の各ケースは Backed Case と呼ばれる。
case が持つ値は整数か文字列のみで、同じ列挙型の中にはいずれか一方の型しか持てない。
値にアクセスするには Suit::Hearts->value
のようにする。
https://wiki.php.net/rfc/readonly_properties_v2
読み込み専用のプロパティ。
class BlogData
{
public readonly Status $status;
public function __construct(Status $status)
{
$this->status = $status;
}
}
一度値が割り当てられた後は読み込みしかできない。 プロパティをパブリックかつ変更不可にできる。
型付きのプロパティにしか使用できない。 型をつけたくない場合は mixed 型を使用する。
デフォルト値を設定できない。 コンストラクタでのデフォルト値設定は大丈夫。
https://wiki.php.net/rfc/first_class_callable_syntax https://www.php.net/manual/en/migration81.new-features.php#migration81.new-features.core.callable-syntax
$foo = [$this, 'foo'];
↓
$foo = $this->foo(...);
$fn = Closure::fromCallable('strlen');
↓
$fn = strlen(...);
...
は何かを省略しているわけではなくてそういう構文。
クロージャを直感的に作ることができるようになった。
クロージャが作成された時点のスコープを尊重する。
例えば $foo = [$this, 'foo'];
とした場合、foo
がプライベートな場合は外から呼び出しができない。
Closure::fromCallable([$this, 'privateMethod']);
とかけば外から呼び出せるが少し長い。
$this->foo(...)
とすれば外から呼び出せて短く書ける。
https://wiki.php.net/rfc/new_in_initializers
class Service
{
private Logger $logger;
public function __construct(
Logger $logger = new NullLogger(),
) {
$this->logger = $logger;
}
}
デフォルト引数でnewを使えるようになった。 他にもアトリビュートの引数、static変数の初期化子、グローバル定数の初期化子でも使えるようになった。
static $x = new Foo;
const C = new Foo;
function test($param = new Foo) {}
#[AnAttribute(new Foo)]
class Test {
public function __construct(
public $prop = new Foo,
) {}
}
クラスのstatic変数や定数に指定した場合、クラスが使用されたタイミングで new が実行される。
ReflectionAttribute::getArguments()
またはReflectionAttribute::newInstance()
を呼び出すたびに、左から右に向かって評価される。ネストしたアトリビュートが書けるようになった。
#[Assert\All(new Assert\NotNull, new Assert\Length(max: 6))]
https://wiki.php.net/rfc/pure-intersection-types
function count_and_iterate(Iterator&Countable $value) {
...
}
複数の型制約を同時に満たすことを要求する際に使用する。 union型と混在して使用することはできない。
交差型に使用できるのかインターフェースかクラスのみ。
https://wiki.php.net/rfc/noreturn_type https://www.php.net/manual/en/language.types.declarations.php#language.types.declarations.never
関数が返らないことを表す戻り値。
関数は exit()
で終了するか、例外が発生するか、無限ループになるかのいずれかとなる。
他の方と一緒にユニオン型にすることはできない。
他の全ての型のサブタイプであり、継承時に他の戻り値を置き換えることができる。
逆に never
を他の方に置き換えることはできない。
関数内で return や yield は使えない。
never
は引数やプロパティの型として使うことはできない。
https://wiki.php.net/rfc/final_class_const
class Foo {
final public const XX = "foo";
}
クラス定数に final
をつけることで、サブクラスでオーバーライドできなくなる。
ちなみにインターフェースの定数はもともとオーバーライドできなかった。 ただし、一度実装(implements)してから継承するとオーバーライドできてしまっていた。 PHP8.1以降ではインターフェースの定数もデフォルトでオーバーライドができるようになり、 finalをつけるとクラスと同様にできなくなるように変更となった。
https://wiki.php.net/rfc/explicit_octal_notation https://www.php.net/manual/en/migration81.new-features.php#migration81.new-features.core.octal-literal-prefix
0o16 === 16; // false
0o16 === 14; // true
8進数のプレフィックスとして 0o
が使えるようになった。
今までは 0
で始まる数値が8進数として扱われていたが、わかりづらかった。
octdec()
や base_convert()
ではすでにこのプレフィックスに対応していたらしい。
https://www.php.net/manual/en/class.fiber.php
プリミティブ? 協調的な並行処理が行える機能。 Fiberはそれぞれが独自のコールスタックを持ち、一時停止や再開が可能。 並行処理を行うには別途イベントループが必要?
Fiberについて記述された記事の翻訳 https://github.com/hysryt/translation/issues/6 https://github.com/hysryt/translation/issues/7
コルーチンやグリーンスレッドというもののPHPでの実装と考えるのが良さそう? Fiberを使えば複数の処理をそれぞれ少しずつ進めるということができる?
※イベントループ イベントの監視と処理を繰り返す無限ループ ここではFiberの状態を監視するループのこと?
$arrayA = ['a' => 1];
$arrayB = ['b' => 2];
$result = ['a' => 0, ...$arrayA, ...$arrayB];
// ['a' => 1, 'b' => 2]
今まで配列で使えていたスプレッド演算子が連想配列でも使用できるようになった。
https://www.php.net/manual/en/function.array-is-list.php
指定した配列がリストであるかどうかを判定する。 配列のキーが 0 から count($array)-1 までの連続した数字で構成されている場合、その配列はリストとされる。
$GLOBALS 配列全体への書き込みアクセスはサポートされない。 たとえば、array_pop($GLOBALS)はエラー。
https://www.php.net/archive/2021.php#2021-11-25-1 https://www.php.net/releases/8.1/en.php https://www.php.net/manual/en/migration81.php