カルテット開発部の澤井です。
久しぶりのブログに、何を書こうかと色々と考えました。
悩んだ結果、やはり仕事で使う機会の多いSymfony
について書こうと思います。
具体的には、Symfony
のイベントを使って、機能を拡張する簡単な例について書きます。
イベントについては、Built-in Symfony Events (Symfony Docs)に詳しい解説があります。
概要
本記事では、以下のような要望について考えます。
- 通常のページでは、コントローラから返された連想配列を、
Twig
テンプレートを使って、HTMLのテーブルとして出力 - 特定のページでは、コントローラから返された連想配列を、CSVファイルとしてダウンロード
本記事の目標は、イベントを使うことで、CSVファイルをダウンロードするという機能を一箇所で管理して、変更がしやすく、再利用性の高いコードを実現することです。
ちなみに、HTTPレスポンスヘッダに、以下の内容を指定することで、CSVファイルをダウンロードさせることができます。
Content-Type
ヘッダに、text/csv
を指定Content-Disposition
ヘッダに、attachment
を指定
コントローラの実装
まずは、@Template
アノテーションを使って、コントローラが返す連想配列を、テンプレートを使って表示します。
次章で、CSVファイルとしてダウンロードする機能を、イベントを使って実現します。
/**
* @Route("/some")
*/
class SomeController extends Controller
{
/**
* @Route("/")
* @Template
*/
public function indexAction(Request $request)
{
// ...
// $dataへ出力内容を保存する処理
// ...
return [ 'data' => $data ]
}
// ...
}
イベントの実装
CSVファイルをダウンロードする機能を、Symfony
のビルトインイベントであるkernel.view
イベントを使って実装します。
今回はサンプルなので、出力するデータは一次元配列かつカンマや改行などを含まないものとします。
namespace AppBundle\Listener;
// ...
class DownloadListener
{
/**
* @param FilterControllerEvent $event
*/
public function onKernelController(FilterControllerEvent $event)
{
$controller = $event->getController();
if (!is_array($controller)) {
return;
}
if ($controller[0] instanceof AssetController) {
$event->getRequest()->attributes->set('is_download', true);
}
}
/**
* @param GetResponseForControllerResultEvent $event
*/
public function onKernelView(GetResponseForControllerResultEvent $event)
{
if ($event->getRequest()->attributes->get('is_download')) {
$controllerResult = $event->getControllerResult();
$response = new Response(
implode(',', $controllerResult['data']),
Response::HTTP_OK,
[
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename=sample.csv',
]
);
$event->setResponse($response);
}
}
}
イベントを使うことで、CSVファイルをダウンロードする機能を、イベントリスナへ集約することができました。
その結果、他のページでCSVファイルをダウンロードする機能が必要になったときに、個別にコントローラへダウンロード機能を追加する必要はありません。
また、CSVファイルの文字コードを変換するといった、新たな要望が発生したときも、イベントリスナの修正だけで対応できます。
まとめ
今回は、イベントを使うことで、変更がしやすくて、再利用性の高いコードにすることができました。
Symfony
は、色々な場面でイベントを使います。
イベントに慣れて、上手に使うことが、Symfony
を使いこなすためのコツの1つかもしれません。
簡単な例でしたが、本記事でイベントの利点が伝われば嬉しいです。
以上、澤井でした。