Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP8.1 #191

Open
hysryt opened this issue Nov 29, 2021 · 13 comments
Open

PHP8.1 #191

hysryt opened this issue Nov 29, 2021 · 13 comments

Comments

@hysryt
Copy link
Owner

hysryt commented Nov 29, 2021

@hysryt
Copy link
Owner Author

hysryt commented Nov 29, 2021

列挙型(Enumerations)

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 インターフェースを実装している。

@hysryt
Copy link
Owner Author

hysryt commented Nov 29, 2021

値に依存した列挙型(Backed Enumerations)

各caseがスカラー値を持つ列挙型

enum Suit: string
{
    case Hearts = 'H';
    case Diamonds = 'D';
    case Clubs = 'C';
    case Spades = 'S';
}

Backed Enum の各ケースは Backed Case と呼ばれる。

case が持つ値は整数か文字列のみで、同じ列挙型の中にはいずれか一方の型しか持てない。
値にアクセスするには Suit::Hearts->value のようにする。

@hysryt
Copy link
Owner Author

hysryt commented Nov 29, 2021

readonly 修飾子

https://wiki.php.net/rfc/readonly_properties_v2

読み込み専用のプロパティ。

class BlogData
{
    public readonly Status $status;
  
    public function __construct(Status $status)
    {
        $this->status = $status;
    }
}

一度値が割り当てられた後は読み込みしかできない。
プロパティをパブリックかつ変更不可にできる。

型付きのプロパティにしか使用できない。
型をつけたくない場合は mixed 型を使用する。

デフォルト値を設定できない。
コンストラクタでのデフォルト値設定は大丈夫。

@hysryt
Copy link
Owner Author

hysryt commented Dec 1, 2021

第一級Callable

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(...) とすれば外から呼び出せて短く書ける。

@hysryt
Copy link
Owner Author

hysryt commented Dec 1, 2021

関数のデフォルト引数でnew

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 が実行される。

  • static変数の初期化子は、制御フローがstatic変数の宣言に到達したときに評価される。
  • グローバル定数の初期化子は、制御フローが定数宣言に到達したときに評価される。
  • 属性の引数は、ReflectionAttribute::getArguments()またはReflectionAttribute::newInstance()を呼び出すたびに、左から右に向かって評価される。
  • 引数のデフォルト値は、引数が明示的に渡されていない関数の呼び出しのたびに、左から右へと評価される。

ネストしたアトリビュートが書けるようになった。

#[Assert\All(new Assert\NotNull, new Assert\Length(max: 6))]

@hysryt
Copy link
Owner Author

hysryt commented Dec 1, 2021

交差型(Intersection)

https://wiki.php.net/rfc/pure-intersection-types

function count_and_iterate(Iterator&Countable $value) {
    ...
}

複数の型制約を同時に満たすことを要求する際に使用する。
union型と混在して使用することはできない。

交差型に使用できるのかインターフェースかクラスのみ。

@hysryt
Copy link
Owner Author

hysryt commented Dec 2, 2021

never型

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 は引数やプロパティの型として使うことはできない。

@hysryt
Copy link
Owner Author

hysryt commented Dec 2, 2021

finalクラス定数

https://wiki.php.net/rfc/final_class_const

class Foo {
    final public const XX = "foo";
}

クラス定数に final をつけることで、サブクラスでオーバーライドできなくなる。

ちなみにインターフェースの定数はもともとオーバーライドできなかった。
ただし、一度実装(implements)してから継承するとオーバーライドできてしまっていた。
PHP8.1以降ではインターフェースの定数もデフォルトでオーバーライドができるようになり、
finalをつけるとクラスと同様にできなくなるように変更となった。

@hysryt
Copy link
Owner Author

hysryt commented Dec 2, 2021

8進数のプレフィックス

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() ではすでにこのプレフィックスに対応していたらしい。

@hysryt
Copy link
Owner Author

hysryt commented Dec 4, 2021

Fiber

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の状態を監視するループのこと?

@hysryt
Copy link
Owner Author

hysryt commented Dec 4, 2021

連想配列のアンパック

$arrayA = ['a' => 1];
$arrayB = ['b' => 2];

$result = ['a' => 0, ...$arrayA, ...$arrayB];

// ['a' => 1, 'b' => 2]

今まで配列で使えていたスプレッド演算子が連想配列でも使用できるようになった。

@hysryt
Copy link
Owner Author

hysryt commented Dec 4, 2021

array_is_list()

https://www.php.net/manual/en/function.array-is-list.php

指定した配列がリストであるかどうかを判定する。
配列のキーが 0 から count($array)-1 までの連続した数字で構成されている場合、その配列はリストとされる。

@hysryt
Copy link
Owner Author

hysryt commented Dec 4, 2021

$GLOBAL配列へのアクセスの制限

$GLOBALS 配列全体への書き込みアクセスはサポートされない。
たとえば、array_pop($GLOBALS)はエラー。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant