<commit_before><sect1 id="zend.controller.action">
    <title>アクションコントローラ</title>

    <sect2 id="zend.controller.action.introduction">
        <title>導入</title>
        <para>
            <code>Zend_Controller_Action</code> は、
            モデル - ビュー - コントローラ (MVC)
            パターンにもとづいたウェブアプリケーションを作成する際に、
            フロントコントローラで使用するアクションコントローラを実装するための抽象クラスです。
        </para>

        <para>
            Zend_Controller_Action を使用するには、
            実際のアクションコントローラ内でこのクラスのサブクラスを作成する必要があります
            (あるいは、作成したサブクラスをもとにしてアクションコントローラを作成します)。
            基本的な使い方としては、まずサブクラスを作成し、
            そしてあなたのサイト上で処理したいさまざまなアクションに対応する
            アクションメソッドを作成するという流れになります。
            Zend_Controller は、このクラス内のメソッドで 'Action'
            という名前で終わるものを見つけると、
            ルーティングやディスパッチの際にそれらを自動的にアクションとして扱います。
        </para>

        <para>
            たとえば、次のようなクラスを見てみましょう。
        </para>

        <programlisting role="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // 何かをします
    }

    public function bazAction()
    {
        // 何かをします
    }
}
]]></programlisting>
            
        <para>
            この FooController クラス ('foo' コントローラ)
            では、ふたつのアクション 'bar' および 'baz'
            が定義されています。
        </para>

        <para>
            もちろんこれ以外にもたくさんの機能があります。
            たとえば初期化アクションを独自に作成したり、
            アクションを指定しなかった (あるいは無効なアクションを指定した)
            際にコールされるデフォルトのアクションを指定したり、
            ディスパッチの前後に実行されるフックを指定したり、
            さまざまなヘルパーメソッドを使用したりといったことができます。
            この章では、アクションコントローラの機能の概要を説明します。
        </para>
    </sect2>

    <sect2 id="zend.controller.action.initialization">
        <title>オブジェクトの初期化</title>

        <para>
            アクションコントローラのコンストラクタをオーバーライドすることもできますが、
            お勧めしません。Zend_Controller_Action::__construct()
            は、リクエストオブジェクトやレスポンスオブジェクトを登録するなどの重要な作業を行います。
            また、フロントコントローラから渡された起動時引数の処理も行います。
            コンストラクタをオーバーライドする場合は、必ずその中で
            parent::__construct($request, $response, $invokeArgs)
            をコールするようにしましょう。
        </para>

        <para>
            初期化作業をカスタマイズするには、コンストラクタをオーバーライドするよりも
            init() メソッドを使うほうがお勧めです。これは、__construct()
            の中で最後にコールされます。たとえば、
            初期化時にデータベースに接続したいなら次のようにします。
        </para>

        <programlisting role="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
    public function init()
    {
        $this->db = Zend_Db::factory('Pdo_Mysql', array(
            'host'     => 'myhost',
            'username' => 'user',
            'password' => '<PASSWORD>',
            'dbname'   => 'website'
        ));
    }
}
]]></programlisting>

    </sect2>

    <sect2 id="zend.controller.action.prepostdispatch">
        <title>ディスパッチ前後のフック</title>

        <para>
            Zend_Controller_Action には、
            リクエストされたアクションの前後にコールされるふたつのメソッドがあります。それが
            preDispatch() と postDispatch() です。
            これらはさまざまな場面で活用できます。
            たとえばアクションを実行する前に認証情報や ACL
            を調べたり (preDispatch() の中で _forward() をコールすると、
            そのアクションの処理は飛ばされます)、
            作成したコンテンツを (postDispatch() で)
            全サイト共通のテンプレートに配置したりといったことが考えられます。
        </para>
    </sect2>

    <sect2 id="zend.controller.action.accessors">
        <title>アクセス用メソッド</title>

        <para>
            さまざまなオブジェクトや変数がオブジェクトに登録されており、
            それぞれにアクセス用メソッドが用意されています。
        </para>

        <itemizedlist>
            <listitem><para>
                <emphasis>リクエストオブジェクト</emphasis>:
                getRequest() を使用してリクエストオブジェクトを取得し、
                それを用いてアクションをコールします。
            </para></listitem>

            <listitem>
                <para>
                    <emphasis>レスポンスオブジェクト</emphasis>:
                    getResponse() を使用して、最終的なレスポンスの内容を取得します。
                    典型的な使用法は、このようになります。
                </para>

                <programlisting role="php"><![CDATA[
$this->getResponse()->setHeader('Content-Type', 'text/xml');
$this->getResponse()->appendBody($content);
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    <emphasis>起動時引数</emphasis>:
                    フロントコントローラは、パラメータを
                    ルータやディスパッチャそしてアクションコントローラに送ります。
                    これらのパラメータを取得するには、
                    getInvokeArg($key) を使用します。あるいは、
                    すべてのパラメータを取得するには
                    getInvokeArgs() を使用します。
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>リクエストパラメータ</emphasis>:
                    リクエストオブジェクトは、_GET や _POST
                    のようなリクエストパラメータのほかに
                    URL のパスで指定したパラメータも収集します。
                    これらを取得するには、_getParam($key) あるいは
                    _getAllParams() を使用します。
                    _setParam() を使用して、リクエストパラメータを設定することもできます。
                    これは、さらに別のアクションに転送する際などに有用です。
                </para>

                <para>
                    パラメータが存在するかどうかを調べる
                    (条件分岐の際に使用します) には、
                    _hasParam($key) を使用します。
                </para>
            </listitem>
        </itemizedlist>
    </sect2>

    <sect2 id="zend.controller.action.utilmethods">
        <title>ユーティリティメソッド</title>

        <para>
            アクセス用メソッド以外にも、Zend_Controller_Action
            にはいくつかのユーティリティメソッドが用意されています。
            これらを使用して、アクションメソッド
            (あるいはディスパッチ前後のフックメソッド)
            でのさまざまな作業を行います。
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis>_forward($action, $controller = null, $module =
                        null, array $params = null)</emphasis>: 
                    別のアクションを実行します。preDispatch() の中でコールすると、
                    リクエストされていたアクションは飛ばされ、
                    新しいアクションを実行します。それ以外の場合は、
                    現在のアクションの処理を済ませた後で
                    _forward() で指定したアクションを実行します。
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>_redirect($url, $code = 302)</emphasis>:
                    別の場所にリダイレクトします。このメソッドには、URL
                    のほかにオプションで HTTP 状態コードを指定します。
                    リダイレクトはその場ですぐ行われ、プログラムの実行はそこで停止します。
                </para>

                <para>
                    状態コードを指定した場合は、リダイレクト時に
                    PHP の header() コマンドでコードが使用されます。
                </para>
            </listitem>
        </itemizedlist>
    </sect2>
</sect1>

<!--
vim:se ts=4 sw=4 et:
-->
<commit_msg>sync Japanese document with r4350.<commit_after><sect1 id="zend.controller.action">
    <title>アクションコントローラ</title>

    <sect2 id="zend.controller.action.introduction">
        <title>導入</title>
        <para>
            <code>Zend_Controller_Action</code> は、
            モデル - ビュー - コントローラ (MVC)
            パターンにもとづいたウェブアプリケーションを作成する際に、
            フロントコントローラで使用するアクションコントローラを実装するための抽象クラスです。
        </para>

        <para>
            Zend_Controller_Action を使用するには、
            実際のアクションコントローラ内でこのクラスのサブクラスを作成する必要があります
            (あるいは、作成したサブクラスをもとにしてアクションコントローラを作成します)。
            基本的な使い方としては、まずサブクラスを作成し、
            そしてあなたのサイト上で処理したいさまざまなアクションに対応する
            アクションメソッドを作成するという流れになります。
            Zend_Controller は、このクラス内のメソッドで 'Action'
            という名前で終わるものを見つけると、
            ルーティングやディスパッチの際にそれらを自動的にアクションとして扱います。
        </para>

        <para>
            たとえば、次のようなクラスを見てみましょう。
        </para>

        <programlisting role="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // 何かをします
    }

    public function bazAction()
    {
        // 何かをします
    }
}
]]></programlisting>
            
        <para>
            この FooController クラス ('foo' コントローラ)
            では、ふたつのアクション 'bar' および 'baz'
            が定義されています。
        </para>

        <para>
            もちろんこれ以外にもたくさんの機能があります。
            たとえば初期化アクションを独自に作成したり、
            アクションを指定しなかった (あるいは無効なアクションを指定した)
            際にコールされるデフォルトのアクションを指定したり、
            ディスパッチの前後に実行されるフックを指定したり、
            さまざまなヘルパーメソッドを使用したりといったことができます。
            この章では、アクションコントローラの機能の概要を説明します。
        </para>
    </sect2>

    <sect2 id="zend.controller.action.initialization">
        <title>オブジェクトの初期化</title>

        <para>
            アクションコントローラのコンストラクタをオーバーライドすることもできますが、
            お勧めしません。Zend_Controller_Action::__construct()
            は、リクエストオブジェクトやレスポンスオブジェクトを登録するなどの重要な作業を行います。
            また、フロントコントローラから渡された起動時引数の処理も行います。
            コンストラクタをオーバーライドする場合は、必ずその中で
            parent::__construct($request, $response, $invokeArgs)
            をコールするようにしましょう。
        </para>

        <para>
            初期化作業をカスタマイズするには、コンストラクタをオーバーライドするよりも
            init() メソッドを使うほうがお勧めです。これは、__construct()
            の中で最後にコールされます。たとえば、
            初期化時にデータベースに接続したいなら次のようにします。
        </para>

        <programlisting role="php"><![CDATA[
class FooController extends Zend_Controller_Action
{
    public function init()
    {
        $this->db = Zend_Db::factory('Pdo_Mysql', array(
            'host'     => 'myhost',
            'username' => 'user',
            'password' => '<PASSWORD>',
            'dbname'   => 'website'
        ));
    }
}
]]></programlisting>

    </sect2>

    <sect2 id="zend.controller.action.prepostdispatch">
        <title>ディスパッチ前後のフック</title>

        <para>
            Zend_Controller_Action には、
            リクエストされたアクションの前後にコールされるふたつのメソッドがあります。それが
            preDispatch() と postDispatch() です。
            これらはさまざまな場面で活用できます。
            たとえばアクションを実行する前に認証情報や ACL
            を調べたり (preDispatch() の中で _forward() をコールすると、
            そのアクションの処理は飛ばされます)、
            作成したコンテンツを (postDispatch() で)
            全サイト共通のテンプレートに配置したりといったことが考えられます。
        </para>
    </sect2>

    <sect2 id="zend.controller.action.accessors">
        <title>アクセス用メソッド</title>

        <para>
            さまざまなオブジェクトや変数がオブジェクトに登録されており、
            それぞれにアクセス用メソッドが用意されています。
        </para>

        <itemizedlist>
            <listitem><para>
                <emphasis>リクエストオブジェクト</emphasis>:
                getRequest() を使用してリクエストオブジェクトを取得し、
                それを用いてアクションをコールします。
            </para></listitem>

            <listitem>
                <para>
                    <emphasis>レスポンスオブジェクト</emphasis>:
                    getResponse() を使用して、最終的なレスポンスの内容を取得します。
                    典型的な使用法は、このようになります。
                </para>

                <programlisting role="php"><![CDATA[
$this->getResponse()->setHeader('Content-Type', 'text/xml');
$this->getResponse()->appendBody($content);
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    <emphasis>起動時引数</emphasis>:
                    フロントコントローラは、パラメータを
                    ルータやディスパッチャそしてアクションコントローラに送ります。
                    これらのパラメータを取得するには、
                    getInvokeArg($key) を使用します。あるいは、
                    すべてのパラメータを取得するには
                    getInvokeArgs() を使用します。
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>リクエストパラメータ</emphasis>:
                    リクエストオブジェクトは、_GET や _POST
                    のようなリクエストパラメータのほかに
                    URL のパスで指定したパラメータも収集します。
                    これらを取得するには、_getParam($key) あるいは
                    _getAllParams() を使用します。
                    _setParam() を使用して、リクエストパラメータを設定することもできます。
                    これは、さらに別のアクションに転送する際などに有用です。
                </para>

                <para>
                    パラメータが存在するかどうかを調べる
                    (条件分岐の際に使用します) には、
                    _hasParam($key) を使用します。
                </para>
            </listitem>
        </itemizedlist>
    </sect2>

    <sect2 id="zend.controller.action.utilmethods">
        <title>ユーティリティメソッド</title>

        <para>
            アクセス用メソッド以外にも、Zend_Controller_Action
            にはいくつかのユーティリティメソッドが用意されています。
            これらを使用して、アクションメソッド
            (あるいはディスパッチ前後のフックメソッド)
            でのさまざまな作業を行います。
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis>_forward($action, $controller = null, $module =
                        null, array $params = null)</emphasis>: 
                    別のアクションを実行します。preDispatch() の中でコールすると、
                    リクエストされていたアクションは飛ばされ、
                    新しいアクションを実行します。それ以外の場合は、
                    現在のアクションの処理を済ませた後で
                    _forward() で指定したアクションを実行します。
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>_redirect($url, array $options =
                        array())</emphasis>:
                    別の場所にリダイレクトします。このメソッドには、URL
                    のほかに任意でオプション群を指定します。
                    デフォルトでは、HTTP 302 リダイレクトを行います。
                </para>

                <para>
                    オプションは、以下のうちのひとつあるいは複数の組み合わせとなります。
                </para>

                <itemizedlist>
                    <listitem>
                        <para>
                            <emphasis>exit:</emphasis> 即時に終了するかしないか。
                            これを指定すると、オープンしたいるセッションをすべて閉じた後にリダイレクトします。
                        </para>

                        <para>
                            このオプションをコントローラ全体で有効にするには、
                            アクセスメソッド <code>setRedirectExit()</code> を使用します。
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <emphasis>prependBase:</emphasis> 
                            リクエストオブジェクトに登録されている基底 URL を
                            この URL の先頭に付加するかどうか。
                        </para>

                        <para>
                            このオプションをコントローラ全体で有効にするには、
                            アクセスメソッド <code>setRedirectPrependBase()</code> を使用します。
                        </para>
                    </listitem>

                    <listitem>
                        <para>
                            <emphasis>code:</emphasis> リダイレクトの際にどの HTTP コードを使用するか。
                            デフォルトでは HTTP 302 を使用しますが、
                            301 から 306 までの任意の値を使用できます。
                        </para>

                        <para>
                            You may set this option globally within the
                            このオプションをコントローラ全体で有効にするには、
                            アクセスメソッド <code>setRedirectCode()</code> を使用します。
                        </para>
                    </listitem>
                </itemizedlist>
            </listitem>

            <listitem>
                <para>
                    <emphasis>render($action = null, $name = null, $noController
                    = false)</emphasis>: ビュースクリプトをレンダリングします。
                    引数を省略した場合は、<code>[コントローラ名]/[アクション名].phtml</code>
                    (<code>.phtml</code> はプロパティ
                    <code>$viewSuffix</code> の値です) が要求されたものとみなします。
                    <code>$action</code> の値を指定すると、
                    <code>[controller]</code> サブディレクトリ内のテンプレートをレンダリングします。
                    <code>[controller]</code> サブディレクトリを無視させるには、
                    <code>$noController</code> に true を渡します。
                    最後にひとつ。レンダリングされたテンプレートは、レスポンスオブジェクトに出力されます。
                    もしレスポンスオブジェクト内の特定の部分に出力したい場合は、その値を
                    <code>$name</code> に渡してください。
                </para>

                <para>
                    例を見てみましょう。
                </para>

                <programlisting role="php"><![CDATA[<?php
class MyController extends Zend_Controller_Action
{
    public function fooAction()
    {
        // my/foo.phtml を出力します
        $this->render();

        // my/bar.phtml を出力します
        $this->render('bar');

        // baz.phtml を出力します
        $this->render('baz', null, true);

        // foo/login.phtml を、レスポンスオブジェクトの 'form' 部に出力します
        $this->render('login', 'form');
        
        // site.phtml を、レスポンスオブジェクトの 'page' 部に出力します
        $this->render('site', 'page', true);
    }
}
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    <emphasis>initView()</emphasis>: ビューオブジェクトを初期化します。
                    <code>render()</code> は <code>initView()</code>
                    をコールしてビューオブジェクトを取得しますが、
                    この初期化はいつでも行うことができます。デフォルトでは、
                    プロパティ <code>$view</code> を作成します。
                    デフォルトで使用するのは <code>Zend_View</code> ですが、
                    <code>Zend_View_Interface</code> を実装したクラスならなんでも使用可能です。
                </para>

                <para>
                    デフォルトの実装は、次のようなディレクトリ構造を想定しています。
                </para>

                <programlisting role="php"><![CDATA[
applicationOrModule/
    controllers/
        IndexController.php
    views/
        scripts/
            index/
                index.phtml
        helpers/
        filters/
]]></programlisting>
                
                <para>
                    言い換えると、ビュースクリプトが
                    <code>views/scripts/</code> の配下にあること、そして
                    <code>views</code> ディレクトリが
                    controllers ディレクトリと同一階層にあることを想定しているということです。
                </para>

                <para>
                    変数の代入やフィルタの登録が必要になった場合などに、
                    <code>initView()</code> を <code>init()</code>
                    あるいはアクションメソッドからコールします。たとえば次のようになります。
                </para>

                <programlisting role="php"><![CDATA[<?php
class MyController extends Zend_Controller_Action
{
    public function init()
    {
        // ビューオブジェクトをすぐに初期化します
        $this->initView();
    }

    public function fooAction()
    {
        // いくつかの変数を初期化します
        $this->view->foo = 'bar';
        $this->view->bar = 'baz';

        // ビューをレンダリングします。変数 'foo' および 'bar' には値が代入されています
        $this->render();
    }
}

class FooController extends Zend_Controller_Action
{
    public function barAction()
    {
        // アクション単位でビューを初期化します
        $view = $this->initView();

        // いくつかの変数を初期化します
        $view->foo = 'bar';
        $view->bar = 'baz';

        // ビューをレンダリングします。変数 'foo' および 'bar' には値が代入されています
        $this->render();
    }
}
]]></programlisting>
            </listitem>

            <listitem>
                <para>
                    <emphasis>getViewScript($action = null, $noController =
                        false):</emphasis> ビュースクリプトのパスを取得します。
                    主に <code>render()</code> から使用しますが、
                    ビュースクリプトのパスを取得したい場面ではいつでも使用できます。
                    あるいは、このメソッドをオーバーライドすることで、
                    コントローラがビュースクリプトのパスを決定する方法を変更することもできます。
                </para>

                <para>
                    上の <code>render()</code> で詳しく説明したように、デフォルトの機能は
                    <code>[コントローラ名]/[アクション名].phtml</code> というビュースクリプトを探すというものです。
                    <code>$action</code> を指定すると、ビュースクリプトのファイル名をオーバーライドします。
                    また <code>$noController</code> に true を渡すと
                    controller サブディレクトリを探さないようにします。
                    プロパティ <code>$viewSuffix</code> をオーバーライドして、
                    ファイルの拡張子 (デフォルトは .phtml) を変更することもできます。
                </para>

                <para>
                    このメソッドをオーバーライドすることで、
                    ビュースクリプトの名前とパスを決定する機能を変更できます。
                </para>
            </listitem>
        </itemizedlist>
    </sect2>
</sect1>

<!--
vim:se ts=4 sw=4 et:
-->

{'fraction_non_alphanumeric': 0.09459949256977165, 'fraction_numerical': 0.0024335939522601357, 'mean_word_length': 1.4046314741035857, 'pattern_counts': {'":': 0, '<': 324, '<?xml version=': 0, '>': 355, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '420439', 'n_tokens_mistral': 8853, 'n_tokens_neox': 7881, 'n_words': 798}