[CakePHP4]定数(const)はどこに書くべきか?マジックナンバーの対処方法

[CakePHP4]定数(const)はどこに書くべきか?マジックナンバーの対処方法
2021年05月31日2021年05月31日

Webアプリケーションを開発する上で、気を付けべきことにマジックナンバーがあります。

個人で開発であればさほど意識されない人もいますが、チームだとマジックナンバーは必ず認識合わせしておく必要があります。

今回CakePHP4でマジックナンバーでの対処方法を紹介します。

そもそもマジックナンバーって何?

マジックナンバーについて簡単に説明すると「何を指しているかわからない数字や文字列」です。

プログラムにおけるマジックナンバー(英: magic number、魔法の数字)とは、何らかの識別子もしくは定数として用いられる、プログラムのソースコード中に書かれた具体的な数値である。そのプログラムを書いた時点では製作者は数値の意図を把握しているが、他のプログラマーまたは製作者本人がマジックナンバーの意図を忘れたときに閲覧すると「この数字の意味はわからないが、とにかくプログラムは正しく動く。まるで魔法の数字だ」という皮肉を含む。

引用:wiki
 

チームで開発を進めると自分自身では意味ある数字や文字列だけど、他人から見ると何を指しているかわからない事象がおこります。

よくありがちなソースコードで説明します。

class Order
{
    public function update($status)
    {
        if ($status === 1) {
           // ステータスが1の場合の処理
        }
        if ($status === 2) {
           // ステータスが2の場合の処理
        }
        // 保存処理
    }

}

上記のソースを見ると、ステータスの「1」って何?「2」は何?と何を指しているかわかりませんよね。

注文受付なのか、キャンセルなのか、返品なのか、他にどんなステータスが存在するのかわかりません。

このステータスの意味を理解するには、ソースコードを解読するか開発した本人に聞くしかありません。非常に非効率な開発の仕方です。

Cakephp4でマジックナンバーを解決する

マジックナンバーを解決する方法として、代表的な方法としてConfigとしてファイルを作成してConfigure::read('huga');で呼び出す方法と、Constクラスファイルを作成して呼び出す方法があります。

configファイルで定数を管理する

定数となるものをconfigファイルに持たせてしまおうという方法があります。

個人的にはおすすめしないですが、やり方としてよく見る方法なので紹介しておきます。

config/bootstrap.php
try {
    Configure::config('default', new PhpConfig());
    Configure::load('app', 'default', false);
    Configure::load('const', 'default');              ←config/const.phpを読み込めるように追記
    
} catch (\Exception $e) {
    exit($e->getMessage() . "\n");
}

configディレクトリに定数を定義するファイルを作成します。

config/const.php
<?php
return [
    'orders' => [
        'status' => [
            'recept' => '1',
            'sent' => '2',
            'cancel' => '3'
        ],
        'status_list' => [
            '1' => '注文受付',
            '2' => '発送済み',
            '3' => 'キャンセル'
        ],
    ],
];

コントローラーなどの処理

app/Http/Controllers/OrdersController.php
use Cake\Core\Configure;
    
...

public function add()
{
   
    $order = $this->Order->newEmptyEntity();
    
    $order = $this->Order->patchEntity($article, $this->request->getData());
    
    if($order->status == Configure::read('orders.status.recept')){
        // 処理
    }
}

viewの処理

resources/views/orders/index.blade.php
<?php
use Cake\Core\Configure;
?>

<div class="form-inline mt-2">
	<?=$this->Form->control('categories._ids', ['multiple'=>'checkbox','options'=>Configure::read('orders.status.satus_list'),'label' => false]); ?>
</div>

上記のようにconfigファイルにしてconstを定義して呼び出すことでマジックナンバーを回避することができます。

しかし、私がおすすめしない理由があります。

  • configファイルにまとめると肥大化します。ファイルを分けしてもconfigファイルが大量にできて管理しづらくなる。
  • 「config('const.orders.recept')」と記述しても、定数ファイルに定義へ移動(Ctrl+クリック)することができません。

英語が苦手な人は「recept」の意味が分からず、定数ファイルをいちいち確認する手間が出てしまいます。

専用のConstクラスファイルを作成する

個人的におすすめな方法が、専用のConstクラスファイルを作成する方法です。

毎度ファイルを作成するのが手間ですが、管理がシンプルで使いやすいです。

ディレクトリ構成はこんな感じで作成します。

src/
 ├ Controller/
 │ └ AppController.php
 ├ Consts/
 │ ├ ArticleConst.php
 │ ├ OrderConst.php
 │ └ UserConst.php
 ├ Model/

Constファイルは下記のように定義していきます。

src/Consts/OrderConst.php
<?php
declare(strict_types = 1);
namespace App\Consts;

class OrderConst
{
    const STATUS_RECEPT = '1';

    const STATUS_RECEPT_NAME = '注文受付';

    const STATUS_SENT = '2';

    const STATUS_SENT_NAME = '発送済み';

    const STATUS_CANCEL = '3';

    const STATUS_CANCEL_NAME = 'キャンセル';

    const STATUS_LIST = [
        self::STATUS_RECEPT => STATUS_RECEPT_NAME,
        self::STATUS_SENT => STATUS_SENT_NAME,
        self::STATUS_CANCEL => STATUS_CANCEL_NAME
    ];
}

templateの処理

templates/Admin/Orders/index.php
<?php
use App\Consts\OrderConst;
?>
<div class="form-inline mt-2">
	<?=$this->Form->control('categories._ids', ['multiple'=>'checkbox','options'=>OrderConst::STATUS_LIST,'label' => false]); ?>
</div>

また、スタッフが操作する画面には選択できるステータスを絞りたいといったことがあります。

そういった場合は、スタッフ用のステータスリストを作成してあげます。

app/Consts/OrderConst.php
<?php
declare(strict_types = 1);
namespace App\Consts;

class OrderConst
{
	...
	// スタッフ変更可能ステータス
    const STUFF_STATUS_LIST = [
        self::STATUS_RECEPT => STATUS_RECEPT_NAME,
        self::STATUS_SENT => STATUS_SENT_NAME,
    ];
}

 このように記述することができます。

さいごに

今回CakePHP4でマジックナンバーの解決方法をまとめてみました。

ここで紹介した以外にもModelで管理したり、外部パッケージをインストールしたりやり方は色々あります。

チームでやりやすい方法を採用してみてください。

コメント

コメントを残す

お名前(任意)
コメント:新規