HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

Zend FrameworkからLaminasに移行する話(10)

はじめに

お仕事で、Zend Frameworkのバージョンアップをしなければならなくなった・・と思ったら、Zend Frameworkはもうなくて、Laminas Projectに移って新たなフレームワークとして公開されている。

いちから勉強しないといけないじゃん、ということで、必要な要件を満たせるかどうかを一歩ずつ調査していく。

要件(10)

10個目の要件は、「__callメソッドを使ったアクションのまとめ上げができること」。

一部のコントローラで__callメソッドを使っているので、念のため、フレームワーク側で変なことをしていないかを確認する。

結論から言うと、コントローラの継承元のAbstractControllerクラスで__callメソッドを使っているので、別のアプローチを考えないといけない。

導入

こちらでセットアップした環境を(コピーして)使っていく。

hhelibex.hatenablog.jp

私は以下のようにコピーを作成。

cp -pr laminas-setup-9-request-parameters laminas-setup-10-call-method
cd laminas-setup-10-call-method

設定・実装

例示するためのコントローラー、ビューを1つ作っていく。

まず、以下の内容で、コントローラmodule/Application/src/Controller/CallController.phpを作成する。今回はアクション名を単にビューに渡すだけにとどめているが、実際にはアクション名に対応する処理を自由に書けばよい。

<?php

declare(strict_types=1);

namespace Application\Controller;

use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\View\Model\ViewModel;

class CallController extends AbstractActionController
{
    public function indexAction()
    {
        return new ViewModel([
            'action_name' => $this->params()->fromRoute('name'),
        ]);
    }
}

次にサービスマネージャの設定をmodule/Application/config/module.config.phpに追加する。新たなrouteを追加する。

<?php
  :
            'call' => [
                'type'    => Segment::class,
                'options' => [
                    'route'    => '/call',
                    'defaults' => [
                        'controller' => Controller\CallController::class,
                        'action'     => 'index',
                    ],
                ],
                'may_terminate' => true,
                'child_routes' => [
                    'detail' => [
                        'type'    => Segment::class,
                        'options' => [
                            'route' => '/:name',
                            'constraints' => [
                                'name' => '[a-zA-Z0-9-]+',
                            ],
                        ],
                    ],
                ],
            ],
        ],
    ],
    'controllers' => [
        'factories' => [
            Controller\IndexController::class => InvokableFactory::class,
            Controller\ForwardedController::class => InvokableFactory::class,
            Controller\RedirectedController::class => InvokableFactory::class,
            Controller\SessionController::class => InvokableFactory::class,
            Controller\RequestParameterController::class => InvokableFactory::class,
            Controller\CallController::class => InvokableFactory::class,
        ],
    ],
  :

ここでやっているのは、/callというrouteの子ルートとして/call/:nameというものを定義してやり、製薬の範囲内で任意のアクション名を所定のメソッド(ここではデフォルトであるindex)に渡せるようにすること。

ここではnameという名前で特定されるものがアクション名になるので、サービスマネージャの設定の:nameと、コントローラのfromRoute('name')は合わせる必要がある。

最後にビューテンプレートをmodule/Application/view/application/call/index.tplに作成する。

Action Name:{$action_name|escape:"html"}

動作確認

以下のURLにアクセスしてみる。

http://192.168.56.xxx/laminas-setup-10-call-method/public/call/test-hoge

当然、test-hogeActiontestHogeActionというメソッドはコントローラに存在しないが、以下のような画面が出るはず。

まとめ

  • Laminas側で__callを使っているので、アプリケーション側で使用することはお勧めできない
  • 代わりに、コントローラであればrouteの設定を使うことで同様の挙動を実現できる