Edited at

EC-CUBE3でHTMLじゃなくてxmlとかで出力する

EC-CUBE3はSilexとSymfony Compornentsを使ってます。

テンプレートはtwigを使って、結果をSymfonyのResponse使って出力してるのですが、HTMLじゃなくてjsonとかXMLとかで特定のURLを出力したい事ってあると思います。僕はありました。

そんな時にどうやるかです。


header("Content-Type: text/xml);とか効かない

たぶん、ControllerでHTTPヘッダ吐いても、ResponseオブジェクトがHTMLとしてContent-Typeを吐いちゃうので効かないです。

なので、テンプレートにもろもろ埋め込んだ後の結果を返す際にResponseオブジェクトを渡して、ResponseオブジェクトでContent-Typeを指定する必要があります。


Sample


Controller

<?php

namespace Eccube\Controller;

use Eccube\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class XmlSampleController
public function ViewXml(Application $app, Request $request)
{
$response = new Response();
$response->headers->set('Content-Type', 'text/xml');//Content-Typeを設定

return $app->render(
'Resource/template/Front/sample_xml.twig',
array('product_id' => 1,"product_name"=>"おなべ")
,$response//第三引数でResponseオブジェクトを渡してあげる
);
}
}


テンプレート

<?xml version="1.0" encoding="UTF-8"?>

<product>
<id>{{ product_id }}</id>
<name>{{ product_name }}</name>
<prodcut>


でも面倒くさい...

こんな風にできたらいいのになぁ...

<?php

namespace Eccube\Controller;

use Eccube\Application;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class XmlSampleController
public function ViewXml(Application $app, Request $request)
{
$app["response"]->headers->set('Content-Type', 'text/xml');//Content-Typeを設定

return $app->render(
'Resource/template/Front/sample_xml.twig',
array('product_id' => 1,"product_name"=>"おなべ")
);
}
}

ちなみにコアのCSVファイルの出力はSymfony\Component\HttpFoundation\StreamedResponseを使ってこんな風に実装されてます。

public function export(Application $app, Request $request)

{
// タイムアウトを無効にする.
set_time_limit(0);

//データ抽出
...

$response = new StreamedResponse();
$response->setCallback(function () use ($app, $request) {

//CSV Service使ってCSVの中身を出力
...
});

$now = new \DateTime();
$filename = 'product_' . $now->format('YmdHis') . '.csv';
$response->headers->set('Content-Type', 'application/octet-stream');
$response->headers->set('Content-Disposition', 'attachment; filename=' . $filename);
$response->send();

return $response;
}

面倒くさいなぁ...


EC-CUBEのカスタマイズはこちら