【PHP】class内で宣言した定数の参照｜self::の有無による違い

web系エンジニアを目指し、MENTAを利用し、PHPを学習している初学者です。
日々学習していることの忘備録、モチベ維持、ちゃんとやってることの証明！の初投稿です。
#対象者
PHPを学びはじめた、初学者
#内容
class内で宣言した定数を参照した時、self::の有無で値がどう変化するか
#動作環境
PHP 7.1.32
#基本のおさらい
###class内で、共有する定数・変数を宣言する
```php5

class A {
    //定数宣言（定数名は$不要、大文字がデフォ）
    const TEISU = '絶対変わらない！';
    //変数宣言（publicの他にprivate,protectedもあるが、ここではアンタッチャブル）
    public $hensu = '代入されれば変わる';
}
```
###宣言した、定数・変数を使う
```php5

class A {
    public function output {
        echo '定数は' . self::TEISU;   //定数は絶対変わらない！
        echo '変数は' . $this->hensu;  //変数は代入されれば変わる
        $this->hensu = '簡単に変わる';
        echo '変数は' . $this->hensu;  //変数は簡単に変わる
    }
```
このように、
定数は```self::定数名```
変数は```$this->変数名```
で使用できます。
「じゃあ定数使うなら、self::必須じゃん。」
と思いますよね。
~~ところが、**定数はそのままでも使えるんです！**~~
（プログラムは動いちゃうけど、）**やっぱり原則使っちゃダメ！**
と、訂正します。
#これが本題！（訂正前）

```php5:ダメな例

//前提：クラス内で宣言した定数を、同じクラスのメソッドで表示
const TEISU = '絶対変わらない！';
const ARRAY_TEISU = array(
        1 => TEISU
);
        
//参照結果
echo self::ARRAY_TEISU[1];  //TEISU
echo self::TEISU;          //絶対変わらない！
echo TEISU;                //TEISU
```
~~つまり、
`self::（配列の）定数名[キー]で、その中身`
`self::定数名で、その中身`
`定数名で、定数そのもの`
が参照される！
以上！今回書きたかったのは、これです。~~
#これが本題！（訂正後）
```php5:良い例

//前提：クラス内で宣言した定数を、同じクラスのメソッドで表示
const TEISU = '絶対変わらない！';
const ARRAY_TEISU = array(
        1 => self::TEISU
);
        
//参照結果
echo self::ARRAY_TEISU[1];  //絶対変わらない！
echo self::TEISU;           //絶対変わらない！
```
つまり、
`定義する時はselfいらないが、使用する時はself::必須！`
###なぜ訂正前で良いと思ってしまったか
**警告を表示させない環境（私の場合はvim）だった為**
vimが悪い訳でなく、php.iniの設定の為です。

記事をご覧いただいた先輩よりご指摘いただきました。
ありがとうございました。
###解決方法
・php.iniの設定を変更する
もしくは、
・`error_reporting(E_ALL);`を追記する

警告を表示する環境にすると、

```php5:悪い例（一部抜粋）
const ARRAY_TEISU = array(
        1 => TEISU
);

echo TEISU;                //TEISU
```
この２箇所で、
`Notice: Use of undefined constant TEISU（定義されてない定数があるよ）`
という警告が表示され
「これじゃダメなんだ。」
と気付くことが出来ます。

~~「constの参照にはself::!!!!!」
と思い込み、長らくエラーに苦しみました。
「そんなバカな・・」
と思った方。これが初学者です！！
それでも信じられない方の為に、どう苦しんだのか実例を晒し、終了とします。~~
失敗実例は、削除するのも寂しいので、今回の知識をいかした内容に訂正しました。
##失敗実例（訂正後）
「メニュー番号を入力させ、機能を呼び出す」
というような課題で、クラスにたくさんの定数を宣言しました。

```php5

class Menu {
    const MENU_MAGAZINE = '雑誌の一覧を見る';
    const MENU_COMIC = '漫画の一覧を見る';
    const MENU_NOVEL = '小説の一覧を見る';
    const END_KEY = '終了'; 
    const MENU_LIST = array(
        1 => self::MENU_MAGAZINE,
        2 => self::MENU_COMIC,
        3 => self::MENU_NOVEL,
        9 => self::END_KEY
    );
```

```$select_menu``` には、厳密なバリデーションチェックの末、```1〜3or9```が入ります。

```php5

    public function main() {
        
        //成功例
        if (self::MENU_LIST[$select_menu] === self::MENU_MAGAZINE) {
            //雑誌のメソッドを実行
        }
        //失敗例
        if (self::MENU_LIST[$select_menu] === MENU_COMIC) {
            //漫画のメソッドを実行
        } 
        
    }
```

`$select_menu=1`の時、成功例のif文に突入！
`self::MENU_LIST[$select_menu] === self::MENU_MAGAZINE`
が成立し（共に「雑誌の一覧を見る」）`if文がtrue判定される`

対して、`$select_menu=2`の時、失敗例のif文に突入！
`self::MENU_LIST[$select_menu] は、'漫画の一覧を見る'`
`MENU_COMIC は、 'MENU_COMIC'`
**（それ以前に、定数をself::〜として使ってないから警告対象）**
となり、
`if文がfalse判定される`
漫画が見たくて「2」を何度押しても、エラーしか出ない悲しい事態になったとさ。
ちゃんちゃん。
#初投稿してみて
なかなか踏み出せなかった、Qiitaへの投稿。
「メモ帳に書いてるだけでは勿体無い！！」
と、思い切って投稿してみました！
良かったのは、**考えが整理される＆間違いに気付ける（指摘していただける）**ことです。
~~投稿前は「self::の有無」ではなく、「配列かどうか」の違いだと勘違いしてた（今となっては謎）ですが、執筆している内に覚醒しました。~~
2時間近く掛かってしまいましたが、それだけでも儲けものです。