Closed51

phpcon2025 聴講セッションまとめ

ろみぃ(konatsu)ろみぃ(konatsu)

https://phpcon.php.gr.jp/2025/

昨日参加したPHPカンファレンス2025(初参加)で聴講したセッションの資料を再度見返しながら、当日の疑問点とかをまとめたり調べてみたりします

要するに、自分の復習用スレッドです

ろみぃ(konatsu)ろみぃ(konatsu)

articlesの方で書くか迷ったけど、最近scrapsばっか書いててこっちの方がつらつら書けて楽しいのでこっちに書くことにした
articlesの方でもなんか書くかもしれないですが

ろみぃ(konatsu)ろみぃ(konatsu)

10:00~
https://fortee.jp/phpcon-2025/proposal/ba73ff87-93ff-4772-8003-43f246a310ae

(僕が探した限りだと現在インターネット上にはスライドが上がってなさそう)

ろみぃ(konatsu)ろみぃ(konatsu)

JITの話が出てたけど、そういえばJITのことちゃんと自分で言語化できるほど身についてないなと思ったので調べてみる。

ろみぃ(konatsu)ろみぃ(konatsu)

PHPはインタプリタ型の言語で、JIT導入以前は、アクセスが来るたびにソースコードを全部読み込みオペコード(opcode)に変換し、逐次実行し、実行が終了したらコードを全て破棄するという方法をとっていた。
OPcacheがこの変換後のオペコードをメモリに保存しておき、次のリクエストでも使う仕組み。

JITは、リクエストが来たらソースコードを全部読んでオペコードにするとこまで同じ。ただ、その後一気にネイティブコードに変換する。
もう一度同じ処理が呼ばれた時は、同じネイティブコードを直接実行するので、処理速度がめっちゃ速くなる。ネイティブコードをメモリに保存して使いまわしたりもできる

ろみぃ(konatsu)ろみぃ(konatsu)

パイプ演算子が便利そうでテンション上がりました
シェルスクリプトっぽいことができるってこと、、?

ろみぃ(konatsu)ろみぃ(konatsu)

https://zenn.dev/demouth/articles/c7a4638075fe12

franken phpにはPHPのソースが埋め込まれていて、それによりPHPがインストールされていなくてもfranken phpだけでPHPファイルを実行できる、という仕組み。
franken php自体はGoで実装されていて、ビルドすると1つの実行ファイルが出来上がり、その実行ファイルとPHPファイルがあればPHPを実行できる、という仕組み。
一般的なPHP拡張機能も一通り入ってる

なので、Webサーバーとして使ったり、PHPが実行できるCLIツールとして使ったりできる

ろみぃ(konatsu)ろみぃ(konatsu)
ろみぃ(konatsu)ろみぃ(konatsu)

最近、仕事の案件で初めてLaravelを使い始めた(個人的に使ったことはあるけど仕事で使ったことはなかった)ので、Laravelの話だ!と思って軽率に選んだ。
結果、あんまりよく理解してなかったCollection型のことがちょっとわかったので良かったです

ろみぃ(konatsu)ろみぃ(konatsu)

メモにNikita氏すげーって書いてあって何だっけ?って思ったけど、スライドのNikita氏偉業シリーズのことだった

ろみぃ(konatsu)ろみぃ(konatsu)

yieldのことは知ってるけど、どういう時にyieldを使うと便利なのかがあまりピンと来ていない

ろみぃ(konatsu)ろみぃ(konatsu)

CollectionとかLazyCollectionとか、もっとちゃんと調べて色々触ってみたい気持ち
ここでやると時間かかりすぎなので別でやりたいな

ろみぃ(konatsu)ろみぃ(konatsu)
ろみぃ(konatsu)ろみぃ(konatsu)

Result型というのを作って、それに成功時の結果も失敗時の結果も書いてreturnしちゃおうという話。
php8.5のattributeで使えるNoDiscardと合わせて使うとシナジーありそうだなと思いながら聞いてた

ろみぃ(konatsu)ろみぃ(konatsu)

ビジネスエラーと技術的エラーでエラーハンドリングの仕方とか扱いを変えようっていうのに共感できた。
例えば、料金の入力をするフォームで、技術(この場合だとデータベースとかアプリケーションのバリデーション)的には整数が入力可能だけど、ビジネス的には100円を下回っちゃいけない、みたいなルールがあった時に、198.8円って入力された時と50円って入力された時のエラーハンドリングが同じでええんかっていう感じよね

ろみぃ(konatsu)ろみぃ(konatsu)

僕はResult型とかじゃなくてExceptionを継承したオリジナル例外クラスみたいなのを作ってcacheするみたいなことをする派だけど、確かにこれだとどこでcacheされるか分からんっていうのはある
cacheが漏れててそのまま500を返しちゃうみたいな

ろみぃ(konatsu)ろみぃ(konatsu)

ビジネスルールとかで「こういう時は失敗するよ」っていうのが明確にあるなら、それ用のResult型を作っちゃうのはアリかもと思いました

ろみぃ(konatsu)ろみぃ(konatsu)
ろみぃ(konatsu)ろみぃ(konatsu)

BDD、名前だけ聞いたことあって詳細は全然知らなかったので興味深く聞かせていただきました
TDDの発展形ってことも知らなかった

ろみぃ(konatsu)ろみぃ(konatsu)

プログラムを書いてるとしばしば「この機能って何に使うんだっけ」とか「誰がどういう場面で使うんだっけ」みたいな視点がうっかり抜けがちなので、そうなる前に自然言語で要求仕様を書いてそれをプログラムのテストに落とし込めるのが良いな〜と思った

ろみぃ(konatsu)ろみぃ(konatsu)
ろみぃ(konatsu)ろみぃ(konatsu)

案件でrachet使ったWebSocketの実装をやったけど、WebSocketも色々ライブラリあるからどれ使うのが正解だったのかな〜っていうのが知りたかったので、そのヒントになればと思って聞きました

ろみぃ(konatsu)ろみぃ(konatsu)
ろみぃ(konatsu)ろみぃ(konatsu)

仮想プロパティとバックドプロパティ

フックの中で自身で同名の実体を正確に参照してれば、バックドプロパティ

ろみぃ(konatsu)ろみぃ(konatsu)
class User
{
    public function __construct (
        public DateTime $birthDate {
            set(DateTimeInterfave|Stringable|string|Closure|int|float $value) {
                // 省略
            }
        }
    ) {
    }
}

// ok
$user = new User(new DateTime('2025-06-29'));

// ok
$user->birthDate = '2025-06-29';

// error
$user = new User('2025-06-29');

set()の引数の型だけ広がってて、コンストラクタの型はそのまま

class User
{
    public function __construct (
        public DateTime $birthDate {
            // これはできない
            set(string $value) {
                // 省略
            }
        }
    ) {
    }
}

→コンストラクタの型からset()の型に広げることはできる。狭めたり変更したりはできない

ろみぃ(konatsu)ろみぃ(konatsu)

元々、僕の中でリスコフって「子ができることは全て親もできる必要があるし、親ができないことを子ができるようになってちゃいけない」くらいの解釈だったんだけど、より具体的にどういうことなのかが理解できた感じがする

ろみぃ(konatsu)ろみぃ(konatsu)

14:55~の枠は、疲れて外を散歩してしまったので聞けませんでした、、
おかげでそれ以降の枠では集中力が復活したので良い判断だったとは思っている

ろみぃ(konatsu)ろみぃ(konatsu)
ろみぃ(konatsu)ろみぃ(konatsu)

実は、オンラインでTS kaigiに参加してて、その中でもプログラミングをするパンダさんの枠を聞いてたので、続きものと知りテンション上がってた

ろみぃ(konatsu)ろみぃ(konatsu)

自分がクリーンなコードを書くのはもちろん、チームメンバーがみんな同じ形でクリーンなコードを書くのが大事。
そのために、全員で認識を合わせるための知識やらドキュメントやら共有の時間やらが大事だなぁと感じました

ろみぃ(konatsu)ろみぃ(konatsu)

3つにレイヤーを分けて、4種類のオブジェクトと3種類のメソッドを使って、クリーンなコードを書く

ろみぃ(konatsu)ろみぃ(konatsu)
ろみぃ(konatsu)ろみぃ(konatsu)

そもそもRLSを知らなかったので、そんなのがあるんだ〜って感じだった

id name
1 テナントA
2 テナントB
id tenant_id name
1 1 太郎
2 1 次郎
3 2 三郎
4 1 四郎

この時、tenant_idが1のデータ以外は無視するようにできるっていうイメージ。
無視というのは、selectもupdateもdeleteも同じ。

無視というか、見ようとするとエラーにするって感じ。0件ですじゃなくて、ちゃんとエラーが出る

ろみぃ(konatsu)ろみぃ(konatsu)

この「見ようとするとエラーにする」というのが、

Eloquentの場合:例えばユーザーログイン時に触っていいテナントのIDを切り替えて、その後も最初に設定した状態で使い続けるイメージ
Doctrineの場合:このEntityManagerはテナントA、こっちはテナントB、みたいな感じで触れるテナントのIDを設定しておいて、どっちを触るかでEntityManagerを変えるイメージ

なので、Doctrineの方がEloquentと比べて明示的になるとのこと

このスクラップは2ヶ月前にクローズされました