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