型に詳しくなりたいのでPHPの勉強会に参加してみた
IT技術
はじめに
こんにちは、たけだです。
今回は、5/30に開催された「PHP TechCafe」に参加してきました。
ここでの気づき・学びを書いていきたいと思います。
「PHP TechCafe」は、株式会社ラクス様所属のエンジニアY-KanohさんとMasaKuさんが主催の、PHPに関する様々なトピックを取り上げ語り合うセッション会(月次開催)です。
今回はPHPにおける「型定義」がテーマになっていました。
参加のきっかけ
PHPを扱う案件で型に関して困った経験があり、型への関心と知見を深めたいと思ったのがきっかけです。
PHP TechCafeの流れ
はじめに、PHPに関するいくつかの記事についてみていく時間がありました。
PHPの新バージョン8.3の動向からxdebug(PHPのデバッグツール)の開発者が寄付を募っているという話まで、広くピックアップされていました。
そして本題の「型」へ...。
PHPと型
PHPは動的型付け言語。
動的型付けとは、変数や関数の引数、戻り値の型を実行時の値によって決定することができる言語です。
コードを書く時点で型を指定しなくても、裏側でよしなにやってくれます。
が、PHPも型宣言できるようになっており、バージョンが上がるにつれて関連機能が追加されています。
型システム
PHPにおける型の歴史は以下の通りです。(引用:PHPリファレンス)
PHP5から型宣言(当時はタイプヒンティングという呼び名)自体は存在していたが、PHP7から本格的に機能拡張されました。
8.2.0 | DNF 型のサポートが追加されました。 |
---|---|
8.2.0 | リテラル型 true のサポートが追加されました。 |
8.2.0 | null と false 型が、独立した型として使えるようになりました。 |
8.1.0 | 交差型のサポートが追加されました。 |
8.1.0 | 戻り値を void とした関数からリファレンスを返すことは、 推奨されなくなりました。 |
8.1.0 | 戻り値にのみ指定できる型として、 never 型のサポートが追加されました。 |
8.0.0 | https://www.php.net/manual/ja/language.types.declarations.php#language.types.declarations.mixed 型のサポートが追加されました。 |
8.0.0 | 戻り値にのみ指定できる型として、 static 型のサポートが追加されました。 |
8.0.0 | union 型のサポートが追加されました。 |
7.2.0 | object 型のサポートが追加されました。 |
7.1.0 | https://www.php.net/manual/ja/language.types.iterable.php 型のサポートが追加されました。 |
7.1.0 | void 型のサポートが追加されました。 |
7.1.0 | nullable な型のサポートが追加されました。 |
また、具体的なPHPの型は以下になります。(引用:PHP:型システム)
- 組み込みの型
- ヌル(null)
- スカラー型:
- 論理値(bool)
- 整数(int)
- 浮動小数点数(float)
- 文字列(string)
- 配列(array)
- オブジェクト(object)
- リソース(resource)
- never
- void
- クラス内での関係を示す相対型: self, parent, static
- リテラル型
- false
- true
- ユーザー定義型 (一般的に、クラス型とも呼びます)
- callable
単一の型を組み合わせて、複合型を作ることができます。 PHP では、次のやり方で型を組み合わせることができます:
- (インターフェイスやクラスの)交差型
- union 型
交差型 は、宣言した複数のクラス型を(単一ではなく) すべて満たす値を受け入れることができます。 交差型を構成する個別の型は、&
記号で結合します。 よって、型 T
, U
, V
の交差型は T&U&V
と書きます。
union 型は、ひとつではなく、 複数の異なる型を値として受け入れることができます。 union 型を構成する個別の型は、|
記号で結合します。 よって、型 T
, U
, V
の union 型は T|U|V
と書きます。 型のひとつが交差型の場合、DNF で記すために 括弧で囲む必要があります。 つまり、T|(X&Y)
と書く必要があります。
- mixed : object|resource|array|string|float|int|bool|null
- iterable : Traversable|array
- Traversableインターフェース
普段の業務では出てこない型もあって勉強になりました。
個人的に以下の型について気になったのでピックアップします。
never型
関数が戻ってこないことを示す戻り値の型。
「終了(exit()など)」、「例外スロー」、「無限ループ」することを示します。
処理が「戻ってこない」ことが重要。
resource型
外部リソースへのリファレンスを保持する型。
fopenやDB接続関連の関数などで使われる型で、普段あまり意識しない型。
resource型は宣言することができません。
1<?php
2// 引数にてresource型を宣言
3function update(resource $file): void {
4 /* 略 */
5}
6// fopenの戻り値の型はresource|false
7update(fopen('php://temp', 'rw'));
これを実行するとエラーになります。
1Warning: "resource" is not a supported builtin type and will be interpreted as a class name. Write "\resource" to suppress this warning in /in/jHcLN on line 4
どうもresource型を宣言すると、PHPが用意した組み込みの型ではなく、クラス名として解釈されるようです。
リテラル型
false型とtrue型があり、それぞれ、”false”と”true”のみを格納できる型。
PHPの標準関数はエラー時にfalseを返す慣習があったそう。
mixed型
厳密、object|resource|array|string|float|int|bool|null
型のエイリアス。つまり「ほぼなんでも型」であり、逆に言えば「何でもない」やつ。
セッション参加者のコメントで個人的に面白かったのが
phpstan level:9(maxレベル)を経験するとmixedという文字がトラウマになる
というコメントです。
PHPStanは型のチェックをしてるツールです。
この設定レベルを最大にすると、「mixedの中身もちゃんと表現してね」と怒られるので、後から型運用を厳密にした場合などに結構怒られます。
僕もこのパターンで、渡ってきた配列の中身の型が定義してないと怒られました。
全体的に、mixedの話になると盛り上がっていたのでPHPerあるあるな型なのかなと思いました。
また、配列と上手いこと付き合っていくことがPHPと仲良くなる近道の1つなのかなとしみじみ感じました。
PHPDoc
PHPのソースコードに記載するコメントで、様々な情報を記せるが、今回は「型」にフォーカスします。
PHPDocで型を書くメリットは以下が挙げられていました。
- 静的解析に使える(PHPStanがここを読み取る)
- PHPの動作に影響がない(コメントのため)
言語が持っている型表現とPHPDocの使い分け
この場で出て来たのが、「既存PJに後から導入するなら、PHPDocから始めてみる」という意見でした。
上でも書いたように動作に影響がないが、型について把握できるようになるためです。
必ずしもこうである必要はなく、「同じ型表現をする機能で意識的に区別するなら」という文脈です。
両方使えるなら使った方が良いのかなと思いました。(配列の中身を注釈するためなど)
感想
セッションに参加している方のPHP知識が深く、勉強になるトピックがいくつもありました。
その一方で、話についていける部分や、あるあるネタがわかる部分もあって、自身の成長もすこし実感できたのが嬉しかったです。
また、1人で学習していると盲点になって気づかないことも、他の人のやり取りを通じて気になるワードや知識を得られるので、こういった会はとても有意義だなと感じました。
今後もこういった場に参加して知見を深めていきたいです。
参考
最後に、PHPの型に関する個人的に参考(勉強)になった記事を貼って終わりにします。
ありがとうございました。
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ
2022年7月に入社しました。開発未経験で未知の領域だらけですが、楽しく学びつつ、早く戦力になれるようにがんばります!