2015年7月8日: Zend Framework 2のTIPS

【ソリューション事業部 スミダ】
少し前にRaspberry piの記事が、当ブログの上位アクセスに食い込んだという話に
気を良くして、今回も懲りずに技術ネタをお送りします。


現在Zend Framework 2(以後ZF2)というフレームワークを使って、仕事をしているのですが
日本語のヘルプサイトやQAが少ないので、調査等に少しばかり難儀しております。
StackOverflow等にはいろいろとQAが載っていますので、英語が得意な方は問題無いかと思います
その中でも、私が調べた事の中で、ZF2を使って開発をするに当たり「これって他の人も調べるのでは?」というTIPSを少しだけ紹介します。

各viewファイルで使える変数をcontrollerの基底クラスから設定したい

各Controllerの親クラスから、各テンプレートファイルで使う為の変数を設定する方法です。
親クラスのonDispatchメソッドに下記の様に記載します。

  1. use Zend\Mvc\Controller\AbstractActionController;
  2.  
  3. class BaseController extends AbstractActionController {
  4.     public function onDispatch(\Zend\Mvc\MvcEvent $e) {
  5.         $e->getViewModel()->setValuables(
  6.             array(
  7.                 "application_name" => "hoge application"
  8.             )
  9.         );
  10.         return parent::onDispatch($e);
  11.     }
  12. }

レイアウトファイルでは下記の様に

  1. <?php echo $this->application_name; ?>

各テンプレートでは下記の様に参照する事が可能です。

  1. <?php echo $this->layout()->application_name; ?>

onDispatchメソッドは各Actionが実行される前に実行されるので、前処理や共通処理を書くのに適していますね。
※戻り値は必ず親のonDispatchの結果を返しましょう。

ページで実行されたSQLを確認したい

ZendDevelopper ToolsBjyProfilerというプラグインを使います。
SQLの実行結果・速度の他、ページ容量やレスポンスタイムまでが画面に表示されます。非常に便利です。

20150708-zf2_developpertool.png
上記のgithubのリンクからzipファイルをDLの上、vendorフォルダに解凍しておきます
Shell(gitコマンド)が使える環境の場合はvendorフォルダ内で下記コマンドを実行します

  1. cd /project/root/path/vendor
  2. git clone git://github.com/zendframework/ZendDeveloperTools.git
  3. git clone git://github.com/bjyoungblood/BjyProfiler.git

その後下記のファイルを
vendor/ZendDeveloperTools/config/zenddevelopertools.local.php.dist
下記のフォルダにコピー
/project/root/path/config/autoload/zenddevelopertools.local.php
application.config.phpの修正(プラグイン有効化)

  1. <?php
  2. /**
  3.  * Configuration file generated by ZFTool
  4.  * The previous configuration file is stored in application.config.old
  5.  *
  6.  * @see https://github.com/zendframework/ZFTool
  7.  */
  8. return array(
  9.     ‘modules’ => array(
  10.         ‘Application’,
  11.         // 下記2行を追加
  12.         ‘ZendDeveloperTools’,
  13.         ‘BjyProfiler’,
  14.         ),
  15.     ‘module_listener_options’ => array(
  16.         ‘module_paths’ => array(
  17.             ‘./module’,
  18.             ‘./vendor’
  19.             ),
  20.         ‘config_glob_paths’ => array(‘config/autoload/{,*.}{global,local}.php’)
  21.         )
  22.     );
  23.  

環境にあったデータベース設定ファイルの修正(global.php local.php等)

  1. <?php
  2. /**
  3.  * Global Configuration Override
  4.  *
  5.  * You can use this file for overriding configuration values from modules, etc.
  6.  * You would place values in here that are agnostic to the environment and not
  7.  * sensitive to security.
  8.  *
  9.  * @NOTE: In practice, this file will typically be INCLUDED in your source
  10.  * control, so do not include passwords or other sensitive information in this
  11.  * file.
  12.  */
  13.  
  14. return array(
  15.     ‘phpSettings’ => array(
  16.         ‘display_startup_errors’      => false,
  17.         ‘display_errors’              => false,
  18.         ‘max_execution_time’          => 1800,
  19.         ‘date.timezone’               => ‘Asia/Tokyo’,
  20.         ‘mbstring.internal_encoding’  => ‘UTF-8’,
  21.     ),
  22.     ‘db’ => array(
  23.         ‘driver’         => ‘Pdo’,
  24.         ‘dsn’            => ‘pgsql:host=****;port=****;dbname=****’,
  25.         ‘database’       => ‘****’,
  26.         ‘username’       => ‘*****’,
  27.         ‘password’       => ‘****’,
  28.     ),
  29.     ‘service_manager’ => array(
  30.         ‘factories’ => array(
  31.             ‘Zend\Db\Adapter\Adapter’ => function ($sm) {
  32.                 $adapter = new BjyProfiler\Db\Adapter\ProfilingAdapter(array(
  33.                     ‘driver’    => ‘pdo’,
  34.                     ‘dsn’            => ‘pgsql:host=****;port=****;dbname=****’,
  35.                     ‘database’  => ‘****’,
  36.                     ‘username’  => ‘****’,
  37.                     ‘password’  => ‘****’
  38.                 ));
  39.  
  40.                 $adapter->setProfiler(new BjyProfiler\Db\Profiler\Profiler);
  41.                 $adapter->injectProfilingStatementPrototype();
  42.   &nbsp
    ;             return $adapter;
  43.             },
  44.         ),
  45.     ),
  46. );
  47.  

これで設定は完了です。
アクセスすると画面下部に冒頭のような黒帯が出現します。(各項目をマウスオーバーする事で詳細が確認出来ます)
※ただし、解析の為内部的にSQLを重複して投げているようなので、当然レスポンスは落ちます。

レスポンスをHTMLでは無く、JSONやプレーンテキストでクライアントに返したい

ZF2のControllerのActionメソッドの戻り値であるViewModelのsetTerminalメソッドを使います

  1. class SampleController extends BaseController
  2.     public function sampleAction() {
  3.         $viewModel = new ViewModel();
  4.         $viewModel->setTerminal(true); // この一文を加える事でlayoutファイルの出力が抑制されます
  5.         $viewModel->setTemplate("sample/sample.txt");
  6.         return $viewModel;
  7.     }
  8. }

レスポンスヘッダーは特に変更されないので、適切なContent-Typeを指定してください。

サーバー側の設定値をクライアントでも使いたい

これはZF2に限ったことでは無いのですが、サーバー側のシステム設定値をクライアント側(Javascript)で
参照したい時があるかと思います。
この場合
・サーバー側と同じ設定値を記載するJSファイルを配置→2重メンテナンスになるので無し
・Ajaxで都度取ってくる→JS書くの面倒。と言うか都度通信走るの非効率じゃない?
上記のような案が出てくるのですが、どれもいまいち
という事で、設定値をクラス内定数で記載している場合のみしか使えませんが
下記の方法を考えてみました。
・ZF2のactionを参照するscriptタグをlayoutファイルに記述
・リクエストを受け取ったactionは設定値クラスをJSで読める様に記載(JSON)
まずは下記のような設定クラスがあったとします。

  1. class Constants {
  2.     const APPLICATION_NAME = "ぼくのかんがえたさいきょうのかーぷだせん";
  3.     const BATTER_1 = "おがた";
  4.     const BATTER_2 = "きくち";
  5.     const BATTER_3 = "まえだ";
  6.     const BATTER_4 = "やまもと";
  7.     const BATTER_5 = "きぬがさ";
  8.     const BATTER_6 = "えとう";
  9.     const BATTER_7 = "のむら";
  10.     const BATTER_8 = "たつかわ";
  11.     const BATTER_9 = "まえだけん";
  12. }

Controllerを追加し、下記Actionを記載します

  1. class ConstantsScriptController extends AbstractSalesController {
  2.      public function onDispatch(\Zend\Mvc\MvcEvent $e) {
  3.         $this->getResponse()->getHeaders()->addHeaderLine("Content-Type", "text/javascript");
  4.         return parent::onDispatch($e);
  5.     }
  6.  
  7.     public function constAction() {
  8.         // ReflectionClassを利用してハッシュ形式で設定を得ます
  9.         $constantsClass= new \ReflectionClass("\Constants");
  10.         $constantsArray = $constantsClass->getConstants();
  11.         $viewModel = new ViewModel(array("consts" => $constantsArray));
  12.         $viewModel->setTerminal(true);
  13.         return $viewModel;
  14.     }
  15. }

このActionに対するviewはこれだけです。

  1. var Constants = Constants || {};
  2. Constants = <?php echo json_encode($consts)?>;

layoutファイルに上記Actionを読み込むscriptタグを追加します。

  1. <?php echo $this->headScript()->prependFile($this->basePath() . ‘/ConstantsScript/const’); ?>

これでグローバル領域にConstsという変数が出来、その中に設定クラスの内容が反映されるようになりました。
20150708-zf2_consts.png
ただし、出力がJSファイルになるため、簡単にコードを読むことが可能にです。
この方法で共有する場合は、設定値にパスワードや認証情報等を含め無いようにします。

バッチファイルを書きたい

バッチファイルを書く際もControllerを作ります。

  1. use Zend\Mvc\Controller\AbstractActionController,
  2.     Zend\Console\Request as ConsoleRequest;
  3.  
  4. class BatchController extends AbstractActionController {
  5.  
  6.     public function doneAction() {
  7.         // —–ここから
  8.         set_time_limit(0);
  9.         $request = $this->getRequest();
  10.  
  11.         if (!$request instanceof ConsoleRequest) {
  12.             throw new \RuntimeException("コンソールからのみ起動できます");
  13.         }
  14.         // —–ここまでは基底クラスを作ってonDispatchにて処理を行うと楽です
  15.  
  16.         // 処理を書く
  17.         // ……
  18.  
  19.         // 終了
  20.         exit(0);
  21.     }
  22. }

ルーティングの設定
Application/config/module.config.php

  1. <?php
  2. return array(
  3.     ‘controllers’ => array(
  4.         ‘invokables’ => array(
  5.             // 追加
  6.             ‘Hoge\Controller\Batch’ => ‘Hoge\Controller\BatchController’
  7.         )
  8.     ),
  9.     // ….中略
  10.  
  11.     // コンソールアプリ設定
  12.     // 書式はWebアプリ設定のrouterと同様
  13.     // Placeholder for console routes
  14.     ‘console’ => array(
  15.         ‘router’ => array(
  16.             ‘routes’ => array(
  17.                 ‘batch’ => array(
  18.                     ‘options’ => array(
  19.                         ‘route’ => ‘batch’,
  20.                         ‘defaults’ => array(
  21.                             ‘__NAMESPACE__’ => ‘Hoge\Controller’,
  22.                             ‘controller’ => ‘Batch’,
  23.                             ‘action’ => ‘done’
  24.                         )
  25.                     )
  26.                 )
  27.             ),
  28.         ),
  29.     ),
  30. );

実行コマンド

  1. cd /path/to/project/public
  2. php index.php batch > /path/to/stdout.log 2>&1 &

Webアプリ側で製造したService等を再利用出来るので、開発工数を減らすことができます。

カテゴリー:
| 投稿者:
DAブログ | DAホールディングス(エクスショップ&ガーデンプラス)

コメント