2013/07/06

PHP GDの"JIS-mapped Japanese font support"オプションが有効になっている場合にZabbixグラフの日本語文字が文字化けする

はじめに

日本語フォントを利用しているのにZabbixのグラフで日本語文字が文字化けしてしまいました。
原因は、長いタイトルの通りPHP GD(グラフィックライブラリ)のJIS-mapped Japanese font support (文字列をSJISへ変換するオプション)が影響していたためであったようで、それについて調べたことをまとめておきます。

環境

確認した環境は以下の通りです。

OS FreeBSD 9.1-RELEASE amd64 (64bit)
Zabbix Zabbix Server 2.0.6
Webサーバ Apache 2.4.4
PHP PHP 5.4.16
DB PostgreSQL 9.2.4
Zabbixフロントエンドディレクトリ /usr/local/www/zabbix2
(FreeBSDデフォルト ※環境に合わせて読み替えてください)

Zabbixグラフの文字化けの原因と対策

Zabbixはユーザごとに管理画面からWebインタフェースの表示言語を設定することができますが、特に何もしないまま"日本語"を選択すると、グラフの日本語文字部分が以下の通り文字化けしてしまいます。


文字化けの原因は英語フォントを利用しているためですので、通常は日本語フォントを指定すれば日本語を表示することができます。
FreeBSDではPortsにIPAフォントが用意されていますので、これをインストールします。

# cd /usr/ports/japanese/font-ipa-uigothic
# make install clean

インストール後、/usr/local/share/font-mplus-ipa/fonts 以下に ipagui.ttf が設置されますので、Zabbixフロントエンドのfontsディレクトリ以下に設置します。ここではシンボリックリンクを作成しています。

# ln -s /usr/local/share/font-mplus-ipa/fonts/ipagui.ttf /usr/local/www/zabbix2/fonts/ipagui.ttf

Zabbixフロントエンドの /usr/local/www/zabbix2/include/defines.inc.php ファイルの38行目を修正します。
フォント名を DejaVuSans から ipagui に変更します。

//define('ZBX_GRAPH_FONT_NAME', 'DejaVuSans'); ※コメントアウト
define('ZBX_GRAPH_FONT_NAME', 'ipagui');

設定を反映させるためにApacheを再起動します。

# service apache24 restart

通常、これで文字化けは解消されるはずですが、私の環境では以下のように文字化けしておりました。

文字化け原因はPHP GD(画像生成ライブラリ)の日本語処理

最初は原因が分からず、DB側の文字コードを見直してみたりしましたが、解消されませんでした。そして、さらに調べるとPHP GD(グラフィックライブラリ)に日本語処理オプションがあるようで、これが影響していることが分かりました。

Zabbixで日本語文字をグラフに埋め込む処理は /usr/local/www/zabbix2/include/graphs.inc.php に記載されています。Zabbix 2.0.6では663行目にあります。

if ($gdinfo['FreeType Support'] && function_exists('imagettftext')) {

詳しい説明は省略しますが、PHPでグラフを扱うには、GDというライブラリをインストールする必要があります。
また、ここで指定されている imagettftext() 関数はTrueTypeフォント(拡張子が".ttf",".ttc"のもの)を扱うための関数で、この関数を利用するにはマニュアルによるとFreeTypeというフォントライブラリをインストールする必要があります。
これらのライブラリはPHPコンパイル時に--with-gd[=DIR], --with-freetype-dir[=DIR]のオプションが指定されていればでインストールされています。

通常これらのライブラリがあれば、日本語フォントを指定することでZabbixのグラフを日本語化できます。

しかし、それでも文字化けが発生するのは、PHPコンパイル時に JIS-mapped Japanese font support (--enable-gd-jis-conv)が有効になっている場合です。
imagettftext() 関数は本来、UTF-8で文字列を扱いますが、JIS-mapped Japanese font support が有効な場合、内部でSJISに変換される処理が行われてしまうため、UTF-8の文字列もSJISに変換され、上記のような文字化けが発生していたようです。

※補足

GDライブラリの設定情報は以下のコードで表示可能です。
[JIS-mapped Japanese Font Support] ==>> OK と表示されれば、JIS-mapped Japanese font support が有効になっています。

<?php
    $buf_info = "";
    $arrInfo = gd_info();
    foreach ($arrInfo as $idx => $buf) {
        if (is_bool($buf)) {
            $buf_info .= "<p>" .htmlspecialchars("[$idx]  ==>> " .($buf ? "OK" : "No Support"))."</p>";
        } else {
            $buf_info .= "<p>" .htmlspecialchars("[$idx]  ==>> $buf") ."</p>";
        }
    }
    echo $buf_info;
?>
対応策

これを解決するためには、日本語フォントサポート(JIS-mapped Japanese font support)オプションを無効になるようにPHPを再コンパイルするか、/usr/local/www/zabbix2/include/graphs.inc.php の664行目にSJISからUTF-8へ変換する以下3行の処理を追加する必要があります。

if ($gdinfo['FreeType Support'] && function_exists('imagettftext')) {
    // JIS-mapped Japanese Font Supportが有効になっている場合、UTF-8 から SJISへの変換する処理を追加
    if ($gdinfo['JIS-mapped Japanese Font Support']) {
        $string = mb_convert_encoding($string, "SJIS", "UTF-8");
    }

ここでは /usr/local/www/zabbix2/include/graphs.inc.php に上記の処理を追加しました。設定を反映させるため、Apacheを再起動します。

# service apache24 restart

再度グラフを確認してみますと、以下の通り日本語が正常に表示されていることを確認できました。

おわりに

PHPの知識が無かったのでこの問題になかなか気付けませんでしたが、Zabbixのソースを見たりPHPのマニュアルを読んで少しですが理解が出来たのでよかったです。

ただ、PHPがZabbixのみで使用されている環境であれば、JIS-mapped Japanese font support が無効になるようPHPを再コンパイルしてしまうほうが良いかも知れません。

参考

0 Comments:

コメントを投稿