Zend FrameworkからLaminasに移行する話(4)
はじめに
お仕事で、Zend Frameworkのバージョンアップをしなければならなくなった・・と思ったら、Zend Frameworkはもうなくて、Laminas Projectに移って新たなフレームワークとして公開されている。
いちから勉強しないといけないじゃん、ということで、必要な要件を満たせるかどうかを一歩ずつ調査していく。
要件(4)
4つ目の要件は、「複数のモジュール間で行き来ができること」。
前回、同一モジュール内でのforward/redirectはできることを確認したが、複数モジュール間でできるのかなど、その辺りも含めて確認していく。
検証ポイントは以下の通り。
- 複数モジュール間でforwardができるかどうか
- その際、渡されたパラメータは引き継げるか(当然できるよね、のテンションで)
- 複数モジュール間でredirectができるかどうか
- その際、パラメータは引き継げないことの確認(これはその性質から当然だよね、のテンションで)
導入
こちらでセットアップした環境を(コピーして)使っていく。
私は以下のようにコピーを作成。
cp -pr laminas-setup-3-forward-redirect laminas-setup-4-multiple-modules cd laminas-setup-4-multiple-modules
設定・実装
新たなモジュールAnotherModule
の追加
新たに作るモジュール名をAnotherModule
とする。
composer.json
を以下のように修正する。
"autoload": { "psr-4": { "Application\\": "module/Application/src/", } },
を
"autoload": { "psr-4": { "Application\\": "module/Application/src/", "AnotherModule\\": "module/AnotherModule/src/" } },
とする。 修正が済んだら、以下のコマンドを実行。
composer dump-autoload
config/modules.config.php
にAnotherModule
を追加する。
<?php /** * List of enabled modules for this application. * * This should be an array of module namespaces used in the application. */ return [ 'Laminas\Router', 'Laminas\Validator', 'Application', 'AnotherModule', 'Smarty', ];
続いて、AnotherModule
を作成していく。
mkdir module/AnotherModule mkdir module/AnotherModule/config mkdir -p module/AnotherModule/src/Controller mkdir -p module/AnotherModule/view/another-module mkdir module/AnotherModule/view/another-module/index mkdir module/AnotherModule/view/another-module/forwarded mkdir module/AnotherModule/view/another-module/redirected
module/AnotherModule/config/module.config.php
を以下の内容で作成する。
<?php declare(strict_types=1); namespace AnotherModule; use Laminas\Router\Http\Literal; use Laminas\Router\Http\Segment; use Laminas\ServiceManager\Factory\InvokableFactory; return [ 'router' => [ 'routes' => [ 'another-module' => [ 'type' => Segment::class, 'options' => [ 'route' => '/another-module[/:action]', 'defaults' => [ 'controller' => Controller\IndexController::class, 'action' => 'index', ], ], ], 'forwarded2' => [ 'type' => Segment::class, 'options' => [ 'route' => '/another-module/forwarded[/:action]', 'defaults' => [ 'controller' => Controller\ForwardedController::class, 'action' => 'index', ], ], ], 'redirected2' => [ 'type' => Segment::class, 'options' => [ 'route' => '/another-module/redirected[/:action]', 'defaults' => [ 'controller' => Controller\RedirectedController::class, 'action' => 'index', ], ], ], ], ], 'controllers' => [ 'factories' => [ Controller\IndexController::class => InvokableFactory::class, Controller\ForwardedController::class => InvokableFactory::class, Controller\RedirectedController::class => InvokableFactory::class, ], ], 'view_manager' => [ 'display_not_found_reason' => true, 'display_exceptions' => true, 'doctype' => 'HTML5', 'not_found_template' => 'error/404', 'exception_template' => 'error/index', 'template_map' => [ 'another-module/index/index' => __DIR__ . '/../view/another-module/index/index.tpl', 'another-module/index/chrome' => __DIR__ . '/../view/another-module/index/chrome.tpl', 'another-module/index/firefox' => __DIR__ . '/../view/another-module/index/firefox.tpl', ], 'template_path_stack' => [ __DIR__ . '/../view', ], 'strategies' => [ 'Smarty\\View\\Strategy', ], ], ];
module/AnotherModule/src/Controller/IndexController.php
を以下の内容で作成する。
<?php declare(strict_types=1); namespace AnotherModule\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; class IndexController extends AbstractActionController { public function indexAction() { $timeStr = 'AnotherModule' . date(' [Y/m/d H:i:s]'); $isFirefox = preg_match('/Firefox/', $_SERVER['HTTP_USER_AGENT']); return new ViewModel([ 'time_str' => $timeStr, 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'is_firefox' => $isFirefox, ]); } }
module/AnotherModule/src/Controller/ForwardedController.php
を以下の内容で作成する。
<?php declare(strict_types=1); namespace AnotherModule\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; class ForwardedController extends AbstractActionController { public function chromeAction() { $a = isset($_GET['a']) ? $_GET['a'] : 'N/A'; $c = isset($_GET['c']) ? $_GET['c'] : 'N/A'; return new ViewModel(['a' => $a, 'c' => $c]); } public function firefoxAction() { $a = isset($_GET['a']) ? $_GET['a'] : 'N/A'; $c = isset($_GET['c']) ? $_GET['c'] : 'N/A'; return new ViewModel(['a' => $a, 'c' => $c]); } }
module/AnotherModule/src/Controller/RedirectedController.php
を以下の内容で作成する。
<?php declare(strict_types=1); namespace AnotherModule\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; class RedirectedController extends AbstractActionController { public function chromeAction() { $a = isset($_GET['a']) ? $_GET['a'] : 'N/A'; $c = isset($_GET['c']) ? $_GET['c'] : 'N/A'; return new ViewModel(['a' => $a, 'c' => $c]); } public function firefoxAction() { $a = isset($_GET['a']) ? $_GET['a'] : 'N/A'; $c = isset($_GET['c']) ? $_GET['c'] : 'N/A'; return new ViewModel(['a' => $a, 'c' => $c]); } }
module/AnotherModule/src/Module.php
を以下の内容で作成する。
<?php declare(strict_types=1); namespace AnotherModule; class Module { public function getConfig(): array { /** @var array $config */ $config = include __DIR__ . '/../config/module.config.php'; return $config; } }
module/AnotherModule/view/another-module/index/index.tpl
を以下の内容で作成する。
Index view (AnotherModule) <br /> PHP version: {$smarty.const.PHP_VERSION} <br /> Time: {$time_str|escape:"html"} <br /> Firefox: {$is_firefox} <br /> User-Agent: {$user_agent|escape:"html"}
module/AnotherModule/view/another-module/forwarded/chrome.tpl
を以下の内容で作成する。
AnotherModule<br> Forwarded Chrome view <br> a={$a}, c={$c}
module/AnotherModule/view/another-module/forwarded/firefox.tpl
を以下の内容で作成する。
AnotherModule<br> Forwarded Firefox view <br> a={$a}, c={$c}
module/AnotherModule/view/another-module/redirected/chrome.tpl
を以下の内容で作成する。
AnotherModule<br> Redirected Chrome view <br> a={$a}, c={$c}
module/AnotherModule/view/another-module/redirected/firefox.tpl
を以下の内容で作成する。
AnotherModule<br> Redirected Firefox view <br> a={$a}, c={$c}
既存モジュールApplication
の修正
module/Application/src/Controller/IndexController.php
を以下のように修正する。
変更点は、以下のメソッドの追加。AnotherModule
へforward/redirectするためのメソッドとなる。
public function redirect2Action() { $isFirefox = preg_match('/Firefox/', $_SERVER['HTTP_USER_AGENT']); if ($isFirefox) { return $this->redirect()->toRoute('redirected2', ['action' => 'firefox']); } else { return $this->redirect()->toRoute('redirected2', ['action' => 'chrome']); } } public function forward2Action() { $isFirefox = preg_match('/Firefox/', $_SERVER['HTTP_USER_AGENT']); if ($isFirefox) { $forward = $this->forward()->dispatch(\AnotherModule\Controller\ForwardedController::class, ['action' => 'firefox']); } else { $forward = $this->forward()->dispatch(\AnotherModule\Controller\ForwardedController::class, ['action' => 'chrome']); } return $forward; }
変更後の内容は以下の通り。
<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; class IndexController extends AbstractActionController { public function indexAction() { $timeStr = date('Y/m/d H:i:s'); $isFirefox = preg_match('/Firefox/', $_SERVER['HTTP_USER_AGENT']); return new ViewModel([ 'time_str' => $timeStr, 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'is_firefox' => $isFirefox, ]); } public function redirectAction() { $isFirefox = preg_match('/Firefox/', $_SERVER['HTTP_USER_AGENT']); if ($isFirefox) { return $this->redirect()->toRoute('redirected', ['action' => 'firefox']); } else { return $this->redirect()->toRoute('redirected', ['action' => 'chrome']); } } public function forwardAction() { $isFirefox = preg_match('/Firefox/', $_SERVER['HTTP_USER_AGENT']); if ($isFirefox) { $forward = $this->forward()->dispatch(ForwardedController::class, ['action' => 'firefox']); } else { $forward = $this->forward()->dispatch(ForwardedController::class, ['action' => 'chrome']); } return $forward; } public function redirect2Action() { $isFirefox = preg_match('/Firefox/', $_SERVER['HTTP_USER_AGENT']); if ($isFirefox) { return $this->redirect()->toRoute('redirected2', ['action' => 'firefox']); } else { return $this->redirect()->toRoute('redirected2', ['action' => 'chrome']); } } public function forward2Action() { $isFirefox = preg_match('/Firefox/', $_SERVER['HTTP_USER_AGENT']); if ($isFirefox) { $forward = $this->forward()->dispatch(\AnotherModule\Controller\ForwardedController::class, ['action' => 'firefox']); } else { $forward = $this->forward()->dispatch(\AnotherModule\Controller\ForwardedController::class, ['action' => 'chrome']); } return $forward; } }
module/Application/src/Controller/ForwardedController.php
を以下のように修正する。
return new ViewModel();
を
$a = isset($_GET['a']) ? $_GET['a'] : 'N/A'; $c = isset($_GET['c']) ? $_GET['c'] : 'N/A'; return new ViewModel(['a' => $a, 'c' => $c]);
に修正。 修正後の内容は以下のようになる。
<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; class ForwardedController extends AbstractActionController { public function indexAction() { $timeStr = date('Y/m/d H:i:s'); $isFirefox = preg_match('/Firefox/', $_SERVER['HTTP_USER_AGENT']); return new ViewModel([ 'time_str' => $timeStr, 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'is_firefox' => $isFirefox, ]); } public function chromeAction() { $a = isset($_GET['a']) ? $_GET['a'] : 'N/A'; $c = isset($_GET['c']) ? $_GET['c'] : 'N/A'; return new ViewModel(['a' => $a, 'c' => $c]); } public function firefoxAction() { $a = isset($_GET['a']) ? $_GET['a'] : 'N/A'; $c = isset($_GET['c']) ? $_GET['c'] : 'N/A'; return new ViewModel(['a' => $a, 'c' => $c]); } }
module/Application/src/Controller/RedirectedController.php
を以下のように修正する。
return new ViewModel();
を
$a = isset($_GET['a']) ? $_GET['a'] : 'N/A'; $c = isset($_GET['c']) ? $_GET['c'] : 'N/A'; return new ViewModel(['a' => $a, 'c' => $c]);
に修正。 修正後の内容は以下のようになる。
<?php declare(strict_types=1); namespace Application\Controller; use Laminas\Mvc\Controller\AbstractActionController; use Laminas\View\Model\ViewModel; class RedirectedController extends AbstractActionController { public function indexAction() { $timeStr = date('Y/m/d H:i:s'); $isFirefox = preg_match('/Firefox/', $_SERVER['HTTP_USER_AGENT']); return new ViewModel([ 'time_str' => $timeStr, 'user_agent' => $_SERVER['HTTP_USER_AGENT'], 'is_firefox' => $isFirefox, ]); } public function chromeAction() { $a = isset($_GET['a']) ? $_GET['a'] : 'N/A'; $c = isset($_GET['c']) ? $_GET['c'] : 'N/A'; return new ViewModel(['a' => $a, 'c' => $c]); } public function firefoxAction() { $a = isset($_GET['a']) ? $_GET['a'] : 'N/A'; $c = isset($_GET['c']) ? $_GET['c'] : 'N/A'; return new ViewModel(['a' => $a, 'c' => $c]); } }
以下のファイルを修正する。
module/Application/view/application/forwarded/chrome.tpl
module/Application/view/application/forwarded/firefox.tpl
module/Application/view/application/redirected/chrome.tpl
module/Application/view/application/redirected/firefox.tpl
修正内容は、以下の記述の追加。ファイルの末尾に追加する。
<br> a={$a}, c={$c}
動作確認
http://192.168.56.xxx/laminas-setup-4-multiple-modules/public/application/forward?a=b&c=d
へアクセスする
Application
モジュールへのforward
Firefoxの場合
http://192.168.56.xxx/laminas-setup-4-multiple-modules/public/application/forward2?a=b&c=d
へアクセスする
AnotherModule
モジュールへのforward
Firefoxの場合
http://192.168.56.xxx/laminas-setup-4-multiple-modules/public/application/redirect?a=b&c=d
へアクセスする
Application
モジュールへのredirect
Firefoxの場合
http://192.168.56.xxx/laminas-setup-4-multiple-modules/public/application/redirect2?a=b&c=d
へアクセスする
AnotherModule
へのredirect
Firefoxの場合
まとめ
- 複数モジュール間でも、forwardやredirectができることが確認できた
- forwardは、
module/*/config/module.config.php
に記述したコントローラーのクラス名を記述する - redirectは、
module/*/config/module.config.php
に記述したrouteの名前を記述する