このページについて
このページではphpで使う事ができる列挙型(enum)の使い方をまとめています。
列挙型
列挙型はphpの8.0以上で使う事ができるようになった、比較的新しい機能です。他の言語においては既に実装されているものですが、phpにおいてはまだ新しい方です。
列挙型は「プログラム中で使う変数の名前をあらかじめ定義しておく」みたいな機能がメインです。関数を書くこともできます。
例えばここ数年で何度か変わってる、消費税。これの計算式は商品価格*消費税なんですが、消費税が変わるたびに消費税倍率を入れてある部分を書き直すのは大変です。
あらかじめ列挙型で「消費税倍率」という名前を作っておき、その部分にのみ消費税倍率の実数値を入力。それ以降のプログラムでは消費税倍率を呼び出せば、実数値も呼び出せるという事になります。
列挙型の書き方
列挙型は通常のクラスと同じように書くんですが、使うのはenumです。そして列挙型の中には、プログラム中で使う値の名前を定義した、caseを並べていきます。caseは1つの列挙型の中で何個も書く事ができます。
enum 列挙型名 {
case 列挙子1;
case 列挙子2;
}
クラスでは変数や関数をpublicなどのアクセス修飾子とともに書きましたが、列挙型ではcaseでそれぞれの名前を書いていくだけとなります。
具体的な書き方はこのようになります。
enum test{
case testA;
case testB;
}
testという名前の列挙型と、その中の列挙子でtestAとtestBを作成するにはこんな感じで書きます。
列挙型と値
列挙型の中身の列挙子は、「名前のみ定義」の仕方と、「名前と値を定義」の2種類があります。上で書いたのは名前のみの定義になります。
値を定義するには通常の変数と同様に定義します。
enum test:string{
case testA = 'A';
case testB = 'B';
case testC= 'C';
}
値を定義する上で注意すべき点がいくつかあります。
値を定義する時の注意点
値を定義して列挙型を作れるわけですが、必ず抑えておかないといけない注意点があります。
- 列挙型が持つ事ができる値は常に1種類
- 列挙型のcaseで文字列(string)と数値(int)を混同することはできません。列挙型全体を通して「文字列のみ」である必要があるというわけです。
もちろん、全てが数値のみの列挙型も可能です。 - 列挙型の名前の後に扱う値の種類を書く
- 列挙型の名前の後に:stringなど、その列挙型のcaseが持つ値の種類を定義する必要があります。
仮に:stringと書いたけど数値(int)を定義した場合はエラーになります。 - 値を定義するならすべてのcaseを定義する
- 1つの列挙型のcaseが4つあるとして、1つは値を定義したけど他3つは未定義なんてことはできません。
値を定義するならその列挙型の他の列挙子すべてを定義する必要があります。逆に全てを未定義にする必要があります。 - 同じ値は定義不可
- 修飾子の名前が異なっていたとしても、同じ値を定義することはできません。
以上の4つは必ず守る必要があります。守らなかった場合はエラーが出ます。
値の有無による呼び方の違い
列挙型も列挙子も、値があるか無いかで呼び方が異なります。
値を含まない列挙子の事をPure case(ピュアケース)と言い、このピュアケースのみで構成された列挙型の事をPure Enumと言います。
値を含む列挙子の事をBacked case(バックドケース)と言い、この列挙子のみで構成された列挙型の事をBacked Enumと言います。
列挙型の値を使う・読み取り
列挙型の値を使う場合、staticメソッドと同じように書きます。簡単な例を書くとこんな感じになります。
enum test{
case testA;
case testB;
}
echo test::testA->name;
enum test2:int {
case testC = 1;
case testD = 2;
}
echo test2::testC->value;
このように書きます。上は値を含まない列挙型で、下が値を含む列挙型です。
値を含まない列挙子は読み取り専用のプロパティを持ちます。nameというプロパティで、列挙子の名前を返すというそのまんまの機能を持っています。
値を含む場合は、追加でvalueというプロパティが使えます。これはその列挙子が持つ値を返すって言う機能を持っています。
なのでこの例で言うと、test::testA->nameは「列挙型(test)のtestAの名前を返す」という書き方になり、下の例で言うとtest2::testC->valueは「列挙型(test2)のtestCの値(value)を返す」という書き方になります。
今回はechoを使って画面に出力するという例でしたが、数値を定義すれば計算式に使うこともできます。
列挙型とインターフェイス
列挙型はインターフェイスを実装する事が可能です。インターフェイスは「処理内容を書かない関数」で、実装とはその中身を書く事を言います。
なのでインターフェイスを定義→列挙型を作成→列挙型の中でインターフェイスの中身を完成という順序を行えば良いことになります。
interface testin{
public function testinA();
}
enum testE implements testin{
case testA;
case testB;
public function testinA(){
var_dump($this);
}
}
testE::testA->testinA();
一番上でtestinというインターフェイスを定義。中にはtestinAという関数名のみ。
真ん中の列挙型で、testinを定義するためにimplementsでtestinを指定し、中身を完成させます。今回はvar_dumpにしました。
そして最後に、列挙型::列挙子->関数名で実行。この時、列挙子が引数扱いになるため、関数で引数を書かなくてもOKですし、関数で使われている$thisに勝手に入ってくれます。
つまり「testEの列挙型のtestAでtestinA関数を実行」という書き方になり、処理の方は「var_dump(testEのtestA)」という感じになります。
ちなみに結果は
enum(testE::testA)
となります。
列挙型とstaticメソッド
staticメソッドは「インスタンスを作成しなくても使える関数」です。通常のクラスはインスタンスを作成し、そのインスタンスから関数を実行させますがstaticメソッドはその必要がありません。
とはいえこの使い方は普通のstaticと全く同じです。何か特別な目的や用途があるのかと言うと、クラスのコンストラクタの代わりをさせるぐらいでしょうか。
enum test {
case testA;
public static function tes(){
echo 1;
}
}
test::testA->tes(); //成功
tes(); //エラー
一番下のように、関数名のみを宣言してもエラーになります。ちゃんと列挙型とか列挙子とか関数名とか指定して宣言してあげましょう。
列挙型の細かい点
ここまで列挙型の大まかな点を中心に解説してきましたが、細かい点もいくつかあります。ここからは補足的な感じになります。
まずは列挙子のcaseですが、これらは全て「列挙型のインスタンス」扱いです。列挙型そのものがクラスで、その中にあるcaseは全て列挙型のインスタンス扱いなので、他でインスタンスを作成することはできません。
そして中身のcaseは全てオブジェクトなので比較演算子が使えません。
列挙型の列挙子は全て定数扱いとなります。つまり定数として扱うこともできるんですが、いい例が思いつかなかったので簡単な例だけ紹介します。
enum test:int {
case A=1;
case B=2;
public const C=self::A; //OK
public const D=self::A + 1000; //エラー
}
echo test::C->name; //A
echo test::C->value; //1
echo test::C->value + 200; //201
constで定数宣言をして、その中身を書くんですがその時に使えるのがself。$thisみたいな感じのものですが、これは「それ自身」を参照する時に使えるものです。列挙子を参照する時にも使えます。
そしてechoでtest::Cのnameとvalueをそれぞれ出力していますが、その中身はcaseAそのものなので、Aと1が出力されます。
仮に5行目のように計算式のような値が変わる可能性がある場合は定数式に入れる事ができないため、エラーとなります。
まとめ
PHPの列挙型はバージョン8.0以上で使う事ができます。列挙型はそのプログラム中で使う変数にあらかじめ名前をつけておく事ができるため、コードの修正なども容易になります。
その他、インターフェイスやstaticメソッドなどクラスと同じような機能も使えるので色々と試してみましょう。
- phpの基礎
- phpとは?JavaScriptとの違いは?みたいなことから、基本の書き方などを解説。
- echoとprint
- 画面に文字を出力する2種類の言語構造の使い方
- 変数
- phpで使える変数の扱い方などを解説しています。
- 変数のスコープ(有効範囲)
- 変数のスコープについての解説です。
- var_dump
- 変数の情報を見ることができる関数
- print_r
- 変数の情報をわかりやすい形式で表示する関数
- 配列と連想配列
- 配列と連想配列の書き方と、便利な関数の解説など。
- key
- 連想配列のキーを返してくれます。内部ポインタ関係あり。
- count
- 配列や連想配列の要素数を数えてくれる関数の使い方解説。
- ソート関数
- 配列に対してソートを行う関数の中から、代表的な5つの使い方解説です。
- array_reverse
- 配列の中身の順番を反転させる関数です。
- array_chunk
- 配列を指定した数で分割させるarray_chunk関数の使い方解説です。
- array_combine
- 2つの配列を足して1つの連想配列にする関数です。
- array_diff
- 2つの配列を比較して、存在しない値を出力する関数
- array_push
- 配列に対して後方に要素を追加する関数
- array_unshift
- 配列に対して先頭に要素を追加する関数。
- array_shift
- 配列の先頭の要素を取り出す関数。
- array_merge
- 複数の配列を統合して1次元の配列にする関数
- array_intersect
- 2つの配列を比較して、両方に共通するものを出力する関数
- include
- includeを使って別のphpファイルを読み込む方法の解説。
- if文
- if文を使って処理を変更させる方法の解説。
- switch文
- switch文を使って複数の処理分岐を行わせたい時に使います。
- forループ
- forループを使って同じ処理を行わせる方法の解説です。
- whileループ
- whileループを使って同じ処理を行わせる方法の解説と注意点。
- do-whileループ
- do-whileループを使って同じ処理を行わせる方法の解説です。
- foreachループ
- foreachループを使って配列内のアイテム全てに処理を行う方法の解説です。
- continue
- ループ処理の残りをスキップしつつ、ループの先頭に戻る制御構造
- ループのネスト構造(入れ子)
- ループの中にループを入れる書き方や考え方の解説。
- function
- functionを使って自作の関数を作成・使用する方法の解説。
- 引数の種類と書き方解説
- functionで扱う引数の種類と書き方を解説
- return
- returnの使い方と関数での使い方解説。
- class
- classを作成して変数と関数を1つにまとめる方法と使い方の解説。
- constructとdestruct
- classのインスタンス作成と同時に処理を行うconstructと、スクリプトの終了と同時に実行するdestructの解説です。
- インターフェイス
- インターフェイスという用語の解説と、実際の使い方解説
- トレイト
- コードを再利用するのに便利なトレイトの解説です。
- 列挙型
- プログラム中で使う変数名をあらかじめ定義しておく。そんな感じの型。
- PDOを使ってMySQLへ接続
- PDOを使ってMySQLへ接続し、データを取得する方法の解説です。
- データの加工と表示
- PDOでデータベースから取得したデータを加工して表示する方法の解説です。
- HTMLフォームのデータ受け取りと表示
- HTMLで作ったフォームからのデータの受け取り方法と、その表示方法の解説です。