EloquentのDB::selectのレスポンスに対して型を定義する
注意
技術的に解決した話ではなくphpdocを書いて頑張る話です
他に良い方法があればこそっとX(旧 twitter)のDMか何かで教えて欲しい
概要
Laravelを使用した開発をしていて、DBへのアクセスをDB::select
などでrawsqlを使用しているのでphpdoc無しだと、その返り値のプロパティに何があるかが分かりづらいので型定義したいと思って調べた
最初はarray{id: string}
のように定義していたがDB::select
は連想配列ではなくstdClass
が返ってくるようなのでdeclare(strict_types=1)
が設定されている場合にエラーになってしまう。なのでobject
として定義し@return object{id: string}
というように書く必要がある
以下サンプル。今回の例はjoinしていないしUser
クラスのようなものがあれば良さそうだが、実際のコードでは色々なテーブルをjoinしているので特定のクラスを定義するのが難しく、仮に用意するならXxxResult
のようなものになるかと思う
<?php
declare(strict_types=1);
/**
* @param $id user id
* @return object{id:string,name:string}|null
*/
function getUser(string $id): object|null {
$sql = "
select
id
, name
from
users
where
id = :id
limit
1
;";
return DB::selectOne($sql, ['id' => $id]);
}
$user = getUser();
$user?->name; // 補完も効いたし、name=stringというのも表示された
これがベストなのかはわからないが、一旦は補完と何型かわかるようになったので良し
余談
tscのような型検査が頑張ってくれる言語ばかり書いてきたのでphpのような言語でどこまでちゃんと書くのかでとても悩んでいる。厳密にphpdocを書いていくと労力が結構かかる気がしているんだけど、何かいい感じの解決方法があったりするのかとても気になる
動かさないと何が返ってくるかがわからなかったり、ドキュメントを見に行ってもmixed
と書かれていて何が返ってくるのかコード確認するしか無さそうなのもなにか手はないものか…