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の出力結果を確認すると、日本語の文字化け問題は解消されているはずだ。