EC-CUBE3系のとあるプラグインをカスタマイズしていた時のこと。

以下のように、一部のDOMをPHPで書き換える処理をしているところがあったのだが、ある問題が発生した。

01
02
03
04
05
06
07
08
09
10
11
12
$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で「テスト」とコンソールに出力したものだが、ご覧のとおり日本語が化けてしまっている。

今回は、この問題を解決するために使ったコードを紹介する。

自作関数を追加する

まず、コントローラー内に以下のメソッド(関数)を追加する。

1
2
3
4
5
6
7
8
9
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の書き換え処理を、以下のように書き直す。

01
02
03
04
05
06
07
08
09
10
11
12
13
$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の出力結果を確認すると、日本語の文字化け問題は解消されているはずだ。