CakePHP2系でService層を作るよ

  • 8
    Like
  • 3
    Comment
More than 1 year has passed since last update.

プロローグ

「おいおい、お前さんまだCakePHP2の世界にとどまってんのか?
CakePHP3はイイ〜世界だぜ、CakePHPの殻を被ったほぼ別物となってやがる。サービス層に該当するModelless Formもあるんだ。2系はどうだい?ん?」
「ち、違う。おれは・・ただ・・CakePHP2で頑張りたいだけなんだ・・!
こいつがどこまでやれるかおれは見てみたいんだ!Service層の機構が無いなら、おれはそれを作り出してみせる・・!」

本題

はい、というわけでCakePHP2系でService層を作ります(唐突)
ぶっちゃけレイヤーを作るのはそんな難しいことではありません。
以下の様に実装すればさっくり出来ます。

Step1.ディレクトリ作成

まずディレクトリ構成について。
Serviceディレクトリをapp直下のControllerやModelと同階層に作成します。

app
├── Controller
├── Model
├── Service ← 追加
├── webroot
└── ***

Step2.bootstrap修正

bootstrap.phpでServiceを認識させてあげる為、以下設定を追加。

app/Config/bootstrap.php
App::build(array(
    'Service' => array('%s' . 'Service' . DS)
), App::REGISTER);

Step3.Serviceクラスを作る

Serviceディレクトリ内にServiceクラスを作ってみましょう

app/Service/PostService.php
<?php
App::uses('Post', 'Model');

class PostService extends Object
{
    function get($id)
    {
        $Post = ClassRegistry::init("Post");
        return $Post->findById($id);
    }
}

Step4.ControllerからServiceを呼ぶ

ここまで来たら後はServiceクラスを参照するだけです。

app/Controller/PostsController.php
<?php
App::import('Service', 'PostService');

class PostsController extends AppController
{
    function sample($id)
    {
        $PostService = ClassRegistry::init("PostService");
        $post = $PostService->get($id);
    }
}

Serviceのロード(App::import)

ちなみにServiceのロードでApp::usesを使うと怒られます

Fatal Error (1): Class 'PostService' not found

これはロードする対象がオートロードの規約に従ってないからだと考えられます。
なのでApp::importを使用します。

まとめ

アプリケーションが小規模であればまだ良いですが、規模が大きくなればなるほどControllerやModelの肥大化問題が発生します。
Modelを扱うService層を導入し、ビジネスロジックを集中させることで、Controllerは窓口の役割に徹することができ、Modelも紐づくテーブルのみを操作するシンプルなものとなります。
もし同じ問題に悩んでいる方の助けになれれば幸いです。

エピローグ

「CakePHP2系から3系にアップデートするのか、別の道を歩むのか、それが最大の問題だ。」