CakePHP const（定数）について

チョといいます。
普段は主にCakePHP3を使ったWebアプリケーションの開発を行っています。

今回は自分がCakePHPを触りながら「定数」をどこでどうやって宣言して、
使っていたかについて書きたいと思います。

## 対象者
CakePHPを使っていてConst（定数）をどこで、どうやって宣言しておいたら、
いいか悩んでいる方々に参考になったらいいなと思います。

## PHP version && CakePHP versionによるconst（定数）の定義方法
PHPやCakePHPはversionによってできることやできないことが変わってくると思います。
今までどんな感じでconst（定数）の宣言のしてきたかをご紹介いたします。

### CakePHP2系、PHP5.*

CakePHP2系 && PHP5.*のversionだと自分は2つの方法で、
開発しました。

まず１つ目はbootstrapに宣言する仕方です。

#### bootstrapに宣言する方法
`Project/app/Config/`のpathにあるbootstrap.phpに共通の定数は宣言しておいて、
環境つまりproductだったらいdevelopだったり環境で分かられる定数は
`Project/app/Config/Bootsrap`に宣言する方法です。

```
// Project/app/Config/bootstrap.php
// 共通に使う定数
define('url','exgample.co.jp');
```

```
// 環境ごとに分かれる定数
// Project/app/Config/Bootsrap/developmentBootstrap.php
define('MAIL_ADDRESS','xxxxx@develop.co.jp');

// Project/app/Config/Bootsrap/productionBootstrap.php
define('MAIL_ADDRESS','xxxxx@product.co.jp');
```

この方法に関してのメリット、デメリットは下記のとおりです。

##### メリット
・環境ごとに分けれるからいい！
・ページがloadされるときに自動で呼ばれるから、他に宣言しなくてもいい

##### デメリット
・個人的にbootstrapにいろんなて意義が混ざってしまうから、fatになることと可読性が悪いと思う

次にはAppConstというconstをまとめて書くclassを作る方法です。

#### AppConstというconstをまとめて書くclassを作る方法
タイトルに書いている通りです。
説明したより宣言方法を見た方が早いと思います。

```
// Project/app/Lib/Utility/AppConst.php

<?php
App::uses('Hash', 'Utility');
class AppConst
{
	const ROLE_ADMIN = 1;
	
    protected static $_values = [];
    
    protected function __construct()
    {
    	// 定数の配列を定義
    	self::$_values['roles'] = [
    		self::ROLE_ADMIN => '管理者'
    	];
    }
    
    public static function getInstance()
    {
        static $instance = null;
        if (null === $instance) {
            $instance = new static();
        }
        return $instance;
    }
    
    public static function read($path)
    {
        return Hash::get(self::$_values, $path);
    }
}
```
上記のように定義します。
なぜ、このようなことをするかというと php7からは定数の配列宣言ができるようになりましたが、その前のversionは使わなかったので、このように定義して使うようにしています。

##### メリット
・bootstrapにまとめて書くよりは可読性が高まる
・const（定数）を一括管理ができる

##### デメリット
・AppConstがfatになる

### CakePHP3系、PHP7.*
前に説明したとおりにPHP7系からは定数の配列の定義が可能になったのと、
Entityという概念がCakePHP3からできたので、この2つを使って定数を定義するといいんじゃないと思いました。

定義の方法は下記のとおり

```
// 共通の定数を宣言するAppEntity作成
// Project/src/Lib/Model/Entity

<?php
declare(strict_types=1);
namespace App\Lib\Model\Entity\;
use Cake\ORM\Entity;

/**
 * AppEntity Entity
 *
 * @property \App\Model\Entity\Unique $unique
 */
class AppEntity extends Entity
{
	// Sex
    const SEX_MAN   = 0;
    const SEX_WOMAN = 1;
    // Sex list
    const SEX_LIST = [
        self::SEX_MAN   => '男性',
        self::SEX_WOMAN => '女性',
    ];
}
```

共通で使う定数を宣言するAppEntityを作った後にそれぞれのEntityにextendsします。

```
<?php
declare(strict_types=1);

namespace App\Model\Entity;

use Cake\ORM\Entity;
use App\Lib\Model\Entity\AppEntity;

/**
 * Man Entity.
 *
 * @author jeong
 */
class Man extends AppEntity
{
	// Sex
    const HOME   = 0;
    const MONEY = 1;
    // Sex list
    const SAMPLE_LIST = [
        self:: HOME,
        self:: MONEY,
    ];
}
```

上記のように定数の意味に会うEntityに定義します。
このように定義して使うことで得られるメリットとデメリットは下記の通りです。

##### メリット
・ctpでもEntityをsetしていたら、普通に定数が使える
・意味があうEntityに宣言するので、可読性が高まる

##### デメリット
・Entityの中にCakePHPのgetter増えてきたらどうしても読みにくくなる

## これから
もっと、効率がいい方法を探して成長し続けたいと思います。
もし、もっといい方法があれば教えてください。