プロローグ
「おいおい、お前さんまだ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::build(array(
'Service' => array('%s' . 'Service' . DS)
), App::REGISTER);
Step3.Serviceクラスを作る
Serviceディレクトリ内にServiceクラスを作ってみましょう
<?php
App::uses('Post', 'Model');
class PostService extends Object
{
function get($id)
{
$Post = ClassRegistry::init("Post");
return $Post->findById($id);
}
}
Step4.ControllerからServiceを呼ぶ
ここまで来たら後はServiceクラスを参照するだけです。
<?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系にアップデートするのか、別の道を歩むのか、それが最大の問題だ。」