EC-CUBE3系のとあるプラグインをカスタマイズしていた時のこと。
以下のように、一部のDOMをPHPで書き換える処理をしているところがあったのだが、ある問題が発生した。
$crawler = new Crawler($content);
$insert_position_id = $this->_getShoppingInsertPosition();
$oldElement = $crawler->filter('#' . $insert_position_id);
$oldHtml = $oldElement->html();
$newHtml = $snipet->getContent() . $oldHtml;
$html = $crawler->html();
$html = str_replace($oldHtml, $newHtml, $html);
$response->setContent($html);
$event->setResponse($response);
上記はEC-CUBE3系のプラグインでよく使われる処理で、SymfonyのCrawlerを使ってHTMLの内容を取得し、一部書き換えてからレスポンスとして返すコードだ。
ただ、この処理をおこなうと日本語が文字化けしてしまうのだ。
以下はJavaScriptで「テスト」とコンソールに出力したものだが、ご覧のとおり日本語が化けてしまっている。
今回は、この問題を解決するために使ったコードを紹介する。
自作関数を追加する
まず、コントローラー内に以下のメソッド(関数)を追加する。
private function getHtml(Crawler $crawler)
{
$html = '';
foreach ($crawler as $domElement) {
$domElement->ownerDocument->formatOutput = true;
$html .= $domElement->ownerDocument->saveHTML();
}
return html_entity_decode($html, ENT_NOQUOTES, 'UTF-8');
}
そして先ほどのCrawlerによるDOMの書き換え処理を、以下のように書き直す。
$crawler = new Crawler($content);
$insert_position_id = $this->_getShoppingInsertPosition();
$oldElement = $crawler->filter('#' . $insert_position_id);
$oldHtml = $oldElement->html();
// 追加
$oldHtml = html_entity_decode($oldHtml, ENT_NOQUOTES, 'UTF-8');
$newHtml = $snipet->getContent() . $oldHtml;
// 変更
$html = $this->getHtml($crawler);
これで再度consoleの出力結果を確認すると、日本語の文字化け問題は解消されているはずだ。