ありがとう。また会おう。

ゆるいかんじで。かたのちからぬいて。やってます。

Zend_Controllerを(モジュールを使わずに)階層化する

あけましておめでとうございます。
この記事は、「Zend Framework 日めくり Calendar 2012」 (http://atnd.org/events/23579) 2日目の記事です。
前日はsasezaki(@)さんの「Zend Framework その7年 (前編)」でした。

いきなり初日とはうってかわって、思い切り実用的な話に持って行きます。
※以下の記事は、Zend Framework Ver1系の話です。

さて、Zend Framework(以下ZF)でアプリを開発していると
だんだんコントローラが増えてきて、どうにかしたいなぁと思ったことありませんか?
そんな時、ZFのお作法的には
「モジュール機構を使え」
・・・とあるのですが
(参考:モジュラーディレクトリ構造の規約の使用 - Zend_Controller - Zend Framework)
このモジュール機構、ある程度機能がMVC単位で切り離せるならいいのですが
特にModelが綺麗に切り離せることがあまりなく
ちょっと無理があるかなぁ・・・と思うことがあったりします。
(まぁZFはディレクトリ構成を比較的自由に組めるので
モジュール機構を使いつつ、モデルは1箇所に固めて共通で使う
・・・ってこともできますが)

で、そんな大げさなことじゃなくて、もっと単純に
「controllerディレクトリにサブディレクトリ掘れればいいのに」
と思うことありませんか?
実はこれ、ZFのオンラインマニュアルには(たぶん)書いてないんですが、できます!
(書籍だと、「ZendFramework徹底入門」にはちらっとだけ書いてあります)
(前段にも書いたとおり、モジュール機構を使わない前提の場合です)

ディレクトリ名・ファイル名はこんな感じにします。

application/controllers/Hoge/FugaPuuController.php

クラス名は

<?php
class Hoge_FugaPuuController extends Zend_Controller_Action
{
    //(アクションメソッド等を記述)
}

とします。
サブディレクトリに当たる部分はアンダーバー"_ "で区切ります

Viewのパスは、たとえばindexアクションなら

application/views/scripts/hoge/fuga-puu/index.phtml

になります。

そして1つ注意が必要なのが、アクセスするURL。
アクセスするURLは以下のようになります。*1

http://www.example.com/hoge_fuga-puu/index

「hoge/fuga-puu/index」ではありませんので注意が必要です。
「単語の区切りはハイフン"-"、ディレクトリ構造はアンダーバー"_"」で区切ることになります。
この例では、ディレクトリ名「hoge」が1単語でしたが、複数単語になる場合も同じくハイフン区切り
(ファイル名とクラス名はUpperCamelCase)になります。

・・・でもこれ、ちょっとカッコ悪いですよね。
ということで、気になる方は、Routerで定義しちゃうといいと思います。

ZFマニュアルのRouterの項、「RewriteRouter での Zend_Config の使用法
のように、Zend_Config_Ini 形式で書くなら

routes.archive.route = "hoge/fuga-puu/index"
routes.archive.defaults.controller = hoge_fuga-puu

とします。
ちなみに、Zend_Controller_Request_Abstract::getControllerName()で得られる
コントローラ名も、こちらの「hoge_fuga-puu」になります。

これをうまく使えば、日々機能拡張のたびに増えるコントローラを
あまり手数をかけずに整理できると思います。


Zend Framework 日めくり Calendar 2012」、明日は@さん
・・・でいいのかな
・・・です!(言い切っちゃったw)
 

*1:スーパープレ記法の中でURLリンクを無効にする書き方がわからん。。。