PHP8 <<Attribute>>

公開日:

オンラインビデオ会議で開催された『関西PHP勉強会』でライトニングトーク(5分)として発表しました。

Download PDF

スライドテキスト

Page 1

PHP8 <<Attribute>>

2020-05-16 #phpkansai
【オンライン】関西PHP勉強会

Page 2

お前誰よ
うさみけんた (@tadsan)

/ Zonu.EXE

  • GitHub/Packagistでは id: zonuexe
    • ピクシブ株式会社 pixiv運営本部
  • Emacs Lisper, PHPer, Rubyist
  • Emacs PHP Modeのメンテナ引き継ぎました
    • 好きなリスプはEmacs Lispです
    • Qiitaに記事を書いたり変なコメントしてるよ

Page 3

Page 4

Page 5

近況

Page 6

3月から 氏んでた

Page 7

最近は
やや元気

Page 8

PHPカンファレンス関西 にはPHP-Parserの話を しようと応募してました

Page 9

はじめに

Page 10

今回紹介する内容に
よって今すぐ何かが変 わることはあまりない

Page 11

少なくともコードを
PHP7系から8に移行
できないと使えない

Page 12

これから一年くらい
かけて対応するツールや フレームワークも徐々に
出てくると思う

Page 13

PHP8時代に心の 準備だけしておこう

Page 14

さて

Page 15

RFC

Page 16

PHPへの 変更提案

Page 17

全てのPHPへの 変更はここで議決

Page 18

ここを観察すれば 次のPHPがわかる

Page 19

ウォッチ
してますか?

Page 20

Page 21

@PHPRFCBot

Page 22

今年12月にリリース予 定のPHP8.0に向けて さまざまな機能が提案

Page 23

Feature freezeは
7月だが既にPHP8向け
にいろいろ決まってる

Page 24

さて

Page 25

Page 26

RFCは受理された が、実装はまだマー
ジされてない

Page 27

過去何度も提案されて
きたが今回の仕様で ようやく受理された

Page 28

そもそも
これは何だ

Page 29

Page 30

このRFCはクラス・プロパティ・関数・ メソッド・引数および定数の宣言に対 する構文的メタデータの構造化された 形式として「アトリビュート」を提案 します。アトリビュートによって宣言 に直接埋め込まれた構成ディレクティ
ブを定義できます。

Page 31

Page 32

似たようなコンセプトは「アノテーション」 としてJavaに、「アトリビュート」として C#・C++・Rust・Hackに、そして 「デコレータ」としてPython・JavaScript
にあります。

Page 33

attributeの定訳とし
ては「属性」。直接関係な いが同じ用語としては HTMLでも非常に重要 な概念。<a href="...">

Page 34

これまでPHPは構造化されていない形 式のメタデータとしてDoc-comment だけを提供しています。ただ、Doc- commentは単なる文字列であり、構 造化情報を保持するための @ ベースの 擬似言語がさまざまなPHPサブコミュ ニティによって提案されてきました。

Page 35

Doc-commentは
リフレクションAPI経由で
実行時に文字列として
取得できる

Page 36

実行時に影響するこ ともあるし、しないこ ともある特殊なやつ

Page 37

/**
* これ

*/

Page 38

/**
*
@return int
*/

Page 39

/**
*
@phpstan-return 1|2
*/

Page 40

/**
*
@deprecated
*/

Page 41

/**
*
@Inject
*/

Page 42

/**
*
@Inject(optional=true)
*/

Page 43

各プロジェクトが 雰囲気で定義してる

Page 44

各プロジェクト固有タグは @phan-param みたいに
共通のタグにprefixを
つけたりアノテーションを \ で名前空間で区切ってる

Page 45

文字列を解析してるだけ だからPHPに存在しない 名前付き引数も好き勝手
に使えるぜ!!!11

Page 46

‒ PHPerKaigi 2020 (Feb 9, 2020)

Page 47

大雑把に言うと
IDEや静的解析のヒント
実行時メタプログラミング
に分類できる

Page 48

なんとなくの風潮として
@tag はタグ、
@Anno("arg", attr=true)は
アノテーションと呼び分け

Page 49

あくまで「なんとなく」で あって、各サブコミュニティ が勝手に実装してるだけ なので厳密な定義はない

Page 50

区別はかなり曖昧だが PSR-19はタグカタログ であり、アノテーション
カタログではない

Page 51

どちらにせよ、PHPス クリプトに書く以上の 付加情報を記述できる

Page 52

あるいは実装から分離して
アノテーションとして
記述することでAOPを実現

Page 53

実行時メタプログ
ラミングの温床

Page 54

例:

Go! AOP

Page 55

そんなわけで
Attributeが入ると

Page 56

/**
* @ExampleAttribute
*/
class Foo
{
// ...
}

Page 57

<<ExampleAttribute>>
class Foo
{
// ...
}

Page 58

// この記法は不採用

@:ExampleAttribute
class Foo
{
// ...
}

Page 59

Doc-commentから取得 できるのは文字列なので、
実行時に活用するには
それを構文解析する必要

Page 60

AttributeはDoc-
commentと同じように実 行時に取得でき、構造化さ
れており構文解析不要

Page 61

好き勝手な記法が使え るタグ/アノテーション と違ってAttributes v2 仕様は単純な関数呼び 出し風構文と静的な式

Page 62

静的な式 = PHPで有効な
式のうちリテラルと定数 と演算子式で解決できる
(実行時に変わらない)

Page 63

たぶんPHP-Parserから もリフレクションと似た
APIが用意されて
簡単に取得できるだろう

Page 64

アトリビュートはク
ラスと同じようにuse
で名前解決できる

Page 65

アトリビュートはクラ
スにマッピングし、
Reflectionから
インスタンスがとれる

Page 66

アトリビュートクラス

<<PhpAttribute>>
class MyAttr
{
function __construct($arg){ // 特にやることがなければ
// 実行時には何もしなくていい

}
}

Page 67

ある意味ではコメントと 同じで、取得されない限り Attributeは実行に影響を
及ぼさない

Page 68

先程のAttributeクラス は静的解析のためのヒン トであって必須ではない

Page 69

その意味でPythonの
デコレータとは
全然違う

Page 70

アトリビュートを加味し てインスタンスを生成す る実行時のファクトリー またはクラスローダーで 近似させることはできる

Page 71

明確な分類はできない
が、タグよりもアノテー
ション系の方がアトリ
ビュートで表現しやすい

Page 72

PHPコンパイラ(処理系) のためのアトリビュート があることが示唆されて いる(詳細はRFC範囲外)

Page 73

PHP
やるじゃん

Page 74

ほんとに?
🤔

Page 75

誰のための
アトリビュート?

Page 76

コンパイラアトリビュー ト(処理系への指示)は
なんとなくわかる

Page 77

ユーザーランドアト
リビュートは…?

Page 78

ユースケース
は…?

Page 79

RFCで実例が 紹介されている

Page 80

これはわかる

Page 81

これも… まあまあ

Page 82

これは… そうなるね

Page 83

ここまでくると…

Page 84

もうつらたん

Page 85

DSLを喜んで覚え直し

たいひとは居るのか?
🙃

Page 86

移行対象ではなく例とし て考えれば、アノテーショ ンベースDSLの新規実装 コストは多少下がってそう

Page 87

とはいえライブラリは既
にあるし、コードイン ジェクションもキャッ
シュ機構があるので実行 時コストには影響しない

Page 88

実はPHP RFC:
Named Argumentsも 復活してPHP8に向けて 議論されそうな雰囲気が あるので影響あるかもね

Page 89

<<Deprecated>>

Page 90

Page 91

アトリビュートの 実際の利用例とし ての新しいRFC

Page 92

trigger_error(E_DEPRE CATED) 相当のコードを 生成する実行エンジン組 み込みのアトリビュート

Page 93

言語組み込みのアトリ
ビュートがある意義もわ かるし、ユーザーランド で再現もめんどいので助
かるといえば助かる

Page 94

関数やメソッド以外 にプロパティや定数 の非推奨化もできる

Page 95

が、メーリングリス トでは存在意義につ
いて割と揉めてる

Page 96

ついでに引数へのア トリビュートの付け かたについても議論

Page 97

普通の実装

function f( $arg1, $arg2
){}

Page 98

引数の非推奨化

function f( $arg1,
$arg2
<<Deprecated>>
){}

Page 99

引数のアトリビュート
ってほんとに
必要なんですか…

Page 100

そもそも名前空間

\Php\Attributes
\Deprecated
じゃなくていいの?

Page 101

Attributesのfuture
scopeの段階では
名前空間がついてたのに、 しれっとグローバル名前
空間に移動している

Page 102

Attributeが 解決できない
問題

Page 103

/** @duplicated */
アノテーション名を
タイプミスすると
(上手に静的解析しない限り) 実行時に無視される

Page 104

<<Duplicated>> アトリビュート名を
タイプミスすると (静的解析しない限り)
実行時に無視される

Page 105

あと単純に名前空間との
相性が悪くて、IDEや
静的解析を使ってないと
useし忘れて無意味な
おまじないとして残り…

Page 106

この問題はアノテー ションベースAOPで 結構深刻だと思うんで すけど皆さんどうやっ
て解決してるんだろ

Page 107

全部のタグ/アノテー ションがアトリビュー
トに移行されるの?

Page 108

されない
と思う

Page 109

いままでのタグ

/** */
@param 1|2 $arg

function f( int $arg1
){}

Page 110

アトリビュートで置換

(イメージ)

use PHPStan\Param as param;

function f(

int $arg1

<<param("1|2")>>
){}

Page 111

IDEの入力補完があっ

たとしても書きにくい
🙃

Page 112

Attributeの
明日はどっちだ

Page 113

PHP先生の
次回作に
ご期待ください