--- title: "PHPerKaigi 2021" date: 2021-03-30T23:22:40+09:00 tags: ["conference", "php", "phperkaigi"] aliases: ['/posts/phperkaigi-2021/'] summary: | 2021-03-26 から 2021-03-28 にかけて開催された、PHPerKaigi 2021 に参加した。 changelog: 2021-03-30: 公開 --- # PHPerKaigi 2021 参加レポ 2021-03-26 から 2021-03-28 にかけて開催された、[PHPerKaigi 2021](https://phperkaigi.jp/2021/) に一般参加者として参加した。 弊社[デジタルサーカス株式会社](https://www.dgcircus.com/) (今年1月から勤務) はダイヤモンドスポンサーとなっており、スポンサー枠のチケットを使わせていただいた。 このようなカンファレンスには初めて参加するのでかねてより心待ちにしていたのだが、生憎2日目から体調を崩してしまい、この記事も途中までとなっている。まだ見ていないセッションも多いが、ひとまず現時点での参加レポを書いておく。 発表はトラック A、B に分かれていたのだが、今回はすべて A トラックを視聴している (切り替えるのが面倒だっただけ)。 ## 凡例 > 発表・スライドのメモ (引用ではない) 感想など ## Day 0 前夜祭 (2021/03/27) ### 17:30 [A] PHP で AWS Lambda > Rails のプロジェクトを PHPer のメンバのみでメンテ > →他のメンバもわかる PHP にリプレースを検討 > > サーバレス > * サーバ・インフラの管理が不要 > * アプリケーションコードの知識だけで保守可能 > > ゼロベースで作れる案件が (Railsの件とは別に) あるため、そちらで試験的に導入? > > AWSの学習 > AWS のドキュメント > DevelopersIO > > AWS Lambda のカスタムランタイムで PHP を動かす > > サーバのセットアップや維持管理を気にしなくて良い > サーバーレスで PHP を動かすツールがすでにある > サーバーレス構築はすんなり > > 今は Laravel がルーティングしている > Laravel Livewire を Lambda に載せられないか? > デプロイ方法は? > バッチ処理は? (Lambda は 15分の制限) > > Lambda でコンテナイメージがサポートされるように > > 抽象化されたもの「だけ」しか知らないよりも具象の理解は助けになる AWS Lambda のような Function as a Service はマイクロサービス化における一つの到達点に思えるのだが、これを使って実際に web サービスを作る具体的なイメージがまだ見えない (注: すべて for me として書いている)。 PHP on AWS Lambda があれだけ簡単に動かせるのには驚いた。 勝手に AWS Lambda だとフットプリントの軽さが求められそう (= PHP + Laravel などでは動かなさそう) だという先入観を持っていたのだが、この発表のデモによればそうでもないらしい。 ### 18:10 [A] 大規模サイトの SEO > 大規模サイト (100万ページ以上) > Google の基準 > > クロールバジェットを意識したSEO > > 大規模サイトでコンテンツが中頻度 (1回/週) で更新 OR 中規模サイト (10,000以上) でコンテンツが目まぐるしく変更される > これを満たさないなら、クロールバジェットを考えなくてもいい > > サーチコンソール > 「カバレッジ」の「除外」 > 多すぎるのは問題→クロールバジェットを浪費している > > * クエリの順番を決める > * 空の値のルールを決めておく > * リダイレクトすればインデックスはうまくいく > * リンクが存在する限りクロールはされる > > リニューアル前のURL > > インデックスは移行される > リンクのURLが存在する限り、別のURLとしてクロールされる > リダイレクトされるとはいえ、リニューアル前のURLは移行した方が良い > リニューアルで無視されるようになったパラメータも注意 > > robotes.txt で拒否しているのにクロールされる > 一時的に拒否を外して 404 や 301 を読ませる > 内部リンクを確認する > JS でのリンクに書き換え > > クエリパラメータからURLのパスに > `/tokyo?area=HOGE` → `/tokyo/HOGE` > > URL 設計だいじ SEO (Search Engine Optimization) は大して知らないので新鮮な話が多かった。その分語れることも少ない……。 ### 18:50 [A] > 知覚可能 > 操作可能 > 理解可能 > 堅牢 ちゃんとしたHTMLを書く (閉じタグ・入れ子構造など) > > * 標準の HTML を適切に使う > * WAI-ARIA > > * キーボードフレンドリー > * マシンフレンドリー > * SEOフレンドリー > > button タグ > →キーボード > h1 タグ > →スクリーンリーダー・クローラ > a タグ > > WAI-ARIA > HTML では表現できないセマンティクスを追加する > > * ロール > * 何をするのか? > * ユーザーアクションによって変化しない > * プロパティ > * 関連づけられたデータ > * ステート > * 現在の状態 > > まずは標準の HTML 要素で解決する > 何でもかんでも WAI-ARIA を使えばいいというものではない > > マウスホバーでツールチップが出てくるが、キーボード操作では出てこない > > VoiceOver > > 全ての属性を使う必要はない > あくまでアクセシビリティを上げるための方法の一つにすぎない つい最近 WAI-ARIA についての記事を読んだばかりだったので個人的にタイムリーな話題だった。(あまりこの言葉を使いたくないのだが) いわゆる「健常者」にとって、こうした問題を普段の生活の中で意識するのは難しい。だからこそ情報へのアンテナは張っておくようにしたい。 ### 19:30 [A] PHP で FUSE 個人的に楽しみだった発表。 > VFS (virtual filesystem) vs 具体的なファイルシステム > > 最適な実装方法は状況により異なる > > アプリケーションに見せるAPIは変えずに実装を隠蔽する→VFS > > カーネルのプログラムを作るのは難しい > * 権限がデカすぎる > * システム全体がクラッシュ > * セキュリティリスク > * 開発サイクルを回しづらい > * ネイティブコードにコンパイルされる言語である必要がある > > Filesystem in USEr space (FUSE) > * 特定の C の関数を呼ぶことで filesystem が作れる > * FFI を持つ言語なら FUSE が使える > > SSHFS / s3fs / Docker Desktop > > Linux 以外でも使える > * dokany (on Windows) > * osxfuse > > VFS: システムコールが呼ばれると、ファイルシステムによってコール > FUSE: カーネル空間からユーザ空間へ通信 > > 高レベルなラッパで型をつける > > PHP 以外では Wordpress を FUSE にマウントする実装がある (C, Python など) > > * grep できる > * sed できる > * 編集できる 期待通りの興味深い発表だった。FUSE 自体も今回の発表で知ったのだが、これ本体の実装を見るのも面白そうだ。 この発表を聞きながらファイルシステムにマウントできそうなものを考えていたのだが、およそ木構造をしているものすべてと言えそうだ (ハンマーしか持っていないと云々)。何かできそうだがなかなか思いつかない。 ## Day 1 (2021/03/27) ### 10:50 [A] ATDD > * ユーザーストーリー > * ユニットテスト > * CI/CD > > ユーザストーリーの受け入れ条件が曖昧になりがち > デグレチェックがユニットレベルでは収まらない場合、手動で同じシナリオをテストしている > > Q2の強化 > アジャイルテストの4象限 > > 技術面/ビジネス面 > 開発チーム支援(コーディング前・コーディング中)/製品批評(コーディング後) > > * Q1: 技術面 & チーム支援 > * TDD > * ユニットテストなど > * Q2: ビジネス面 & チーム支援 > * ATDD > * ビジネス面の受け入れテストで駆動する > > Agile Alliance > ユーザストーリーのスキルレベルを高める > > テストピラミッド > > * UI Tests > * Service Tests > * Unit Tests > > * 異なる粒度のテストを書く > * 高レベルになるほど、持つべきテストは少なくなる > * ピラミッド型になる > > 高レベルテストが多すぎる→アイスクリームコーン アンチパターン > > ATDD (Acceptance TDD) > API経由・UI経由での高レベルテスト E2E test > > ストーリ受け入れテスト > > 入れ子のフィードバックループ > ATDD(外側) と TDD(内側) > > 外部品質・内部品質 > > バーティカルスライスのデリバリー > > * cucumber > * gauge > * behat > > ユビキタス言語 > 手動テストもspecに書く > 自動化は可能だがコスパが悪い > 失敗することがわかっているテスト(レッドテスト)はCIから外す > 失敗時の原因究明が難しい > 饒舌なエラーメッセージ > 状況のスナップショット > > Continuous Testing User Acceptance Test (UAT) くらいの規模になると個人開発・趣味開発では触れない領域なので、大いに勉強になった。スライドに添付されている資料が相当に充実していたので、これを読むのが本番といった様相すら感じる。 高レベルテストの自動化は現在のプロジェクトでも感じており、自動化のチャンスは伺っている。とはいえセッションでも指摘されているように自動化することにコストがかかりすぎる領域があるのも事実で、そのバランスが難しい。 ### 11:50 [A] 型解析を用いたリファクタリング 型のある世界で生きてきた身として大いに楽しみにしていた発表。 > * PHPStan > * Phan > * Psalm > > autoload も認識できる > bootstrapFiles > > 編集箇所と利用箇所を CI でチェック > ルールレベルを徐々に引き上げていく > 警告が多すぎると見落としてしまう・無視されやすくなる > > 型がついていないことによるエラーが多い > > 型よりも詳細な検査 `Util_Assert::min` > > SQL を静的解析 > placeholder の型付け > > 警告レベルを低いレベルから導入 > タイプヒントを積極的に書いていく > PHPStan の拡張を追加する 昨今、動的型付き言語での型宣言・型アノテーション・型ヒントの導入が相次いでいる。長らく静的型付き言語を書いてきた私からすると、ようやく気づいたかといったところだが、ともかく型を導入する言語が増えてきた。 今のプロジェクトでも新しく追加するコードには型をつけるよう努めているが、どうしても古いコードには型がついていない。個人的には型のないコードに対してどう型を自動的に付けるかという点に興味があり、その点で Ruby の typeprof には注目している。 ### 12:30 [A] 昼食をとっていた。事前に何か食料を買っておくべきだった。 ### 13:10 [A] Documentation as Code この発表も以前から非常に楽しみにしていた。 > 開発開始までのオーバーヘッド > 新規にチームにジョイン > 担当範囲外の機能を理解 > オンボーディングのコスト > > PHPerKaigi 2020 で発表あり > > 継続的にシステムの理解を助けるドキュメント > > 継続的ドキュメンテーション > システムとドキュメントの乖離 > > 書いてあることが間違っている・足りない > * 徐々にずれていく > * システムの更新タイミングとドキュメントの更新タイミングに差がある > > システムとドキュメントは対応関係がある > * 間違ったドキュメント > * 存在しないドキュメント > > システムとドキュメントの乖離を定量化する > 継続的に > システムの更新に近いタイミングで ドキュメントを更新し続ける > > Documentation as Code > > コードと同じツールでドキュメントを書く > * issue tracker > * vcs > * plain text markup > * automation > > 開発者 > システム > ドキュメント > 構造化データ > ソフトウェア > > システムから構造化データを抽出する > PHPDoc > OpenAPI > > ビュー 関心ごとに合わせてアーキテクチャを一つ以上の側面(断面)で説明する > > ビューの単位でドキュメントに > > スタックトレースからのドキュメント生成 ドキュメントの管理は現プロジェクトでも課題と感じている。作られた当初は正しくても、実態と乖離していくのを止めるのは困難を極める。全体的に興味深い発表だったが、特にスタックトレースからのドキュメント生成というアイデアに惹かれるものを感じた。スタックトレースという実態と不可分な (乖離しない) 情報を起点にするのは理にかなっている。問題はトレースをいつ、どう取るかだろうか。それを自動化しなければ、実態との乖離が避けられないだろう。 ### 14:10 [A] cookie による session 管理 全体的に基本的な話だったので特に触れない。Cookie やセッションの話としては非常に分かりやすくまとめられていたので、知らない人が学ぶにはいい教材だろう。 ### 14:50 [A] PHP のエラーと例外 > エラー PHPエンジンがエラーを通知する > 例外 プログラムが投げる > > PHP7-8とエラー > > PHPエンジンのエラーの一部が \Error に変換されるようになった > → try-catch で捕捉できる > > \Error は例外とは異なる > > PHP8 でエラーレベルの引き上げ > > * 捕捉すべきもの > * recoverable > * 捕捉すべきでないもの > * unrecoverable > * 開発時に対処できるもの > > 例外 > * 捕捉して事後処理 > * 捕捉せず(or 捕捉した上で)さらに上に是非を問う > > 開発段階で例外を把握し、ハンドリングを考えておく > > \Throwable \Exception と \Error > > \Error はキャッチすべきでない > > * \Error > * 本番で起きてはいけない > * \LogicException > * 本番で起きてはいけない > →生じないのだから捕捉もしない > > * \RuntimeException > * 起こるかもしれないので本番環境でも考慮する > > 捕捉して対応するのではなく、未然に防ぐ > > 独自例外を使う > \Exception を投げてしまうと、 > catch (\Exception)せざるを得ない > →catch 範囲が広すぎる > > SPL の例外を使う > > 例外翻訳 > 上位のレイヤが下位のレイヤの例外を捕捉し、上位レイヤのAPIに「翻訳」する > 下位レイヤの知識に依存させない > > @throws > 捕捉してほしい例外を書き連ねておく > > 呼び出しもとに負わせたい責任 PHP を学んでいる途中の私としては、今まさに聞きたい発表だった (現時点で PHP を書き始めてから 4ヶ月ほどになる)。 個人的に例外やエラーを最もうまく扱っているのは Go、Swift、Rust、Haskell などのエラーを「値として」扱う言語だと思っている。try-catch は通常の処理フローを完全に壊してしまう上、構文としても重すぎる。値としてのエラー通知は C言語時代への回帰ともいえるが、その頃と異なるのはエラーを暗黙のうちに握り潰すことがないということだ。これらの言語は型を持っており、静的に検証ができる (C のそれはまともな型付けではない。念のため)。 PHP のように、すでに例外が言語システムに根ざしている言語ではどうすればよいか。この場合も同じく静的検証の力を借りることになるだろう。 ### 15:30 [A] Laravel のメール認証 Laravel の知識がない私にはまったくついていけなかった。また、個人的にタイトルがややミスリーディングに感じた。 ### 16:10 [A] gRPC > Unary RPCs > Server streaming RPCs > Client streaming RPCs > Bidirectional streaming RPCs > > Protobuf > > 実装とAPIが乖離しにくい > 自動生成 > 複数言語でも相互に使える > > マイクロサービスのサービス通信 > スマホアプリ > ゲームサーバ > > PHP では? > > PHP ではストリーミングが難しい > リクエストごとにプロセスが使い捨て > > PHP ではgRPCのクライアントしか対応していない > > gRPC-Web > ブラウザで扱うためのJSライブラリ+プロトコル > > HTTP/1.1 でも使える > Unary RPC と Server streaming RPC のみ > > Envoy > Nginx などで相互に gRPC と gRPC-Web で変換 > > Amp > イベント駆動な並行処理のフレームワーク > > HTTP/2 対応 > > C#のgRPC-Webが楽 (発表の中でもまさに同じことをおっしゃっていたが) PHP 以外の方が向いているだろう、というのが第一の感想である。gRPC はそれ自体というよりも Protobuf というエコシステムに乗れることのメリットが大きいと感じる。そのエコシステムにうまく乗れない時点で、うーんという感じ。 ### 16:50 [A] アーキテクチャテスト > Independent Core Layer Pattern > > 開発初期のアーキテクチャが崩れる > アーキテクチャ観点のコードレビューができない > > どこにクラスを置けばよいか? > ドキュメントがない > > アーキテクチャ設計に関する知識が属人化・暗黙知化 > > ガイドライン > * 最初にルールを決めるのは簡単 > * ルール通り作り始めるのも簡単 > * →維持するのが難しい、人が決めたものゆえ壊れやすい > > PHP の特性 > * クラスは public > * 可視性の制御が public / protected / private のみ > * 依存関係の制御が困難 > > アーキテクチャテスト > クラスの依存関係や実装ルールをコードとして表現し、自動テスト化する > > * deptrac > * phpat > > Independent Core Layer Pattern > > アーキテクチャテストの失敗 > * 実装誤り > * or アーキテクチャが適切でない > * 開発の過程でフィードバックしていく > > モジュラーモノリス→マイクロサービスへ ## Day 2 (2021/03/28) 冒頭に書いた通り、2日目から体調が悪くまともに聴けていない。途中までは頭痛を我慢しつつ見ていたのだが、まともに入ってこなかった。 残念ではあるが、いずれにせよ見られていない発表は他にもあるので、今週末にでもまとめて見ようと思う。 ## 全体の感想 Day 2 にほとんど参加できなかったのは残念だが、イベント自体は大変楽しく、また興味深いものであった。自分がまったく知らない領域の話を聞けるのはこうしたイベントならではだと感じる。オンライン開催ゆえ現地に行く必要がなく、気軽に参加できたのも (特に初参加者として) 嬉しいポイントだった。 今回、雑談/登壇者への質問等向けに Discord サーバもあったのだが、こちらは参加こそしたものの ROM のままになってしまった。発表に1ウィンドウ、メモを書くのに1ウィンドウ、Discord 表示に 1ウィンドウで私にはもう脳のリソースとディスプレイのスペースが追いつかなかった (さらにいうと Zoom でアンカンファレンスもやっていたようだ。こちらはまったく参加していない)。 1つ個人的な反省点としては、一つ一つのセッションを真剣に聞き過ぎたというものがある。もっと適当に聞いておけばよかった。これだけだと大変語弊があるのだが、言い方を変えると、Discord しかりアンカンファレンスしかり「このイベントのこの瞬間にしかないコンテンツ」に触れずに、後から見返せる発表やスライドに注力してしまった、ということだ。発表の詳細な見直しはあとからできるのだから、今しかできないことを考えるべきだった。 まあ初カンファレンスだし、とお茶を濁しておこう。 さて、カンファレンスで一つ気になったことがある。それは、Discord という書き込み場所が増えたことでニコ生のコメントの流量が吸い取られてしまったのではないか、という点だ。ニコニコだけ見ていると過疎っているかのように見えた発表も、Discord の方では盛り上がっている、というのを何度か見かけた。ニコニコのコメント方式は盛り上がりを如実に反映するが、逆もまたしかり。Discord があったこと自体はプラスだったと思うが、この点はマイナスだったのではないかと感じる。 ------- 最後になりましたが、毎年の PHPerKaigi 開催にご尽力されている皆様、スピーカーの皆様、楽しい3日間でした。ありがとうございました! (ずっと常体で書いてしまったのでいきなり仏頂面から笑顔になったようで気持ち悪い) ではまた来年。