はじめに
自分が理解できていない部分を整理しながら、知識を少しずつ深めていくことを目的にこの記事を書いています。
そのため、内容の中には誤りが含まれている可能性もありますが、その点はご容赦ください。
間違いなどがあれば、ぜひコメントなどで教えていただけると嬉しいです!
今日整理していく内容
- アクセサ(Accessor)がクエリを発行している
- $thisとは?
- : void などの戻り値型宣言
アクセサ(Attribute)がクエリを発行している
開発現場の中で、「アクセサ(Accessor)がクエリを発行している」と言われても、その場では理解できませんでした。クエリを発行している部分については意味が分かりますが、「アクセサ(Accessor)??」となりました。
アレクサなら家に設置しているんですが……って感じですね。ということで整理していきます。
アクセサとは、データベースからデータを取得する際に一時的に走る処理のことのようです。また、データベースからデータを取得する際に、値の加工ができる仕組みのようです。
今回、これが悪さをしていた例があります。「アクセサの中でリレーションメソッドを呼び出してクエリを発行する」実装をすると、属性取得時に予期せぬデータベース問い合わせが走ることがあります。
おかげさまで、「アクセサ=ただ値を返すだけ」ではなく、「裏でクエリを発行する」ことをしていました。
// ❌ クエリを毎回発行するアクセサ
protected function lastPostDate(): Attribute
{
return new Attribute(
get: fn (): ?string => $this->posts()->max('created_at')
);
}
// ✅ クエリを抑えられるアクセサ
protected function lastPostDateEfficient(): Attribute
{
return new Attribute(
get: fn (): ?string => $this->posts->max('created_at')
);
}
簡単にまとめるとこんなイメージです。これは、はまりましたね💦
-
$this->posts()
→ メソッド呼び出し。毎回クエリを発行。 -
$this->posts
→ リレーション結果(コレクション)を使う。すでに読み込み済みなら追加クエリなし。
$thisとは?
あっ、これも最初見た時に「ん??」ってなりましたね。PHPの疑似変数 $this
だと?? 今操作しているクラスのインスタンス自身を指すみたいですね〜〜。
というか、そもそもなぜ $this
が必要なんでしょう? 調べてみたところ、クラス定義の内部では、プログラムからアクセス可能なオブジェクト名を特定できないため、クラスの中からそのクラス内の関数や変数にアクセスするために、疑似変数 $this
を使用するとのことでした。
つまり、$this
は「自分自身の」または「現在のオブジェクト」という意味。つまり $this
は「今動いているこのモデル(自分)」を指すもの、と覚えておきます。
ChatGPTに生成してもらったサンプルコードを載せておきます。
class User extends Model
{
public function greet(): string
{
// $this は「このユーザー自身」
return "Hello, " . $this->name;
}
}
$user = new User(['name' => 'Kota']);
echo $user->greet(); // Hello, Kota
: void などの戻り値型宣言
最後は、戻り値型宣言ですね。これはPRのレビュー時に指摘されて、意識してつけるようになりました。
void
はTypeScriptでも使った気がしますが、忘れていることが多いので簡単にまとめていきます。
戻り値型宣言を使うことで、「この関数/メソッドはどんな型を返すか」を明示できます。
これも簡単なサンプルコードをChatGPTに生成してもらったので、載せておきます。
function logMessage(string $msg): void
{
echo $msg;
// return; // ← 値を返さないのでこのように書いても OK
}
function add(int $a, int $b): int
{
return $a + $b;
}
logMessage("Hello, world!"); // 出力のみ、戻り値なし
echo add(2, 3); // 5
上記では logMessage
が : void
を使っており、「何も返さない」という意味になります。
「戻り値に型(: int, : string, : void など)をつける」ことは、コードを**“より信頼できる・安全で・わかりやすい”**ものにするための仕組みのようです。TypeScriptの型宣言に近いイメージですね。
間違いに早めに気づけて、バグ防止にもなりそうです。今後も意識していきたいと思います。
まとめ
ここまで読んでいただきありがとうございました!
今回の記事では、
- アクセサ(Accessor)がクエリを発行している
- $thisとは?
- : void などの戻り値型宣言
について整理しました。
自分の中で「なんとなくわかっているつもり...」だった部分を改めて言語化してみると、まだ理解が浅いところが多いと実感しました。
少しずつでも前進できるよう、これからもドキュメントをしっかり読みながら理解を深めていきたいと思います!
明日も頑張ります!💪