仙台の山奥で自転車に乗ったり転んだり

愛車の GIOS でサイクリングしたりポタリングしたり、それをブログに記録してみたり。ロードバイクや自転車や坂のことを書いてみたり。ときたまプログラムのことを忘れないようにメモってみたり。

PHPでShit_JISとEUC-JPで外字処理

UNICODEであればほぼ無意味な作業、リクエストなどのたびにShit_JISの外字を〓に置換。(基幹系からのデータとか、携帯ユーザとかSJISじゃなきゃダメな制約のある場合の話。)

よくやる処理って下のような置換作業。
これってUNICODEなら全く無駄な作業だよなと思う、というかこの実装も凄く無駄でダサい気がする。
こんな時代遅れないけてない処理を、誰いけてる人に書き直してほしいな。

/**
 * Shift_JIS外字を「〓」に変換
 * 
 * @param  string $attribute
 * @return string 
 */
function convert_sjis_gaiji($attribute)
{
    $gaiji_ranges = array(
            array(0x8540,0x857E),array(0x8580,0x859E), //   9区
            array(0x859F,0x85FC),                      //  10区
            array(0x8640,0x867E),array(0x8680,0x869E), //  11区
            array(0x869F,0x86FC),                      //  12区
            array(0x8740,0x877E),array(0x8780,0x879E), //  13区-NEC特殊記号-
            array(0x879F,0x87FC),                      //  14区
            array(0x8840,0x887E),array(0x8880,0x889E), //  15区
            array(0xEB40,0xEB7E),array(0xEB80,0xEB9E), //  85区
            array(0xEB9F,0xEBFC),                      //  86区
            array(0xEC40,0xEC7E),array(0xEC80,0xEC9E), //  87区
            array(0xEC9F,0xECFC),                      //  88区
            array(0xED40,0xED7E),array(0xED80,0xED9E), //  89区-NEC拡張外字
            array(0xED9F,0xEDFC),                      //  90区-NEC拡張外字
            array(0xEE40,0xEE7E),array(0xEE80,0xEE9E), //  91区-NEC拡張外字
            array(0xEE9F,0xEEFC),                      //  92区-NEC拡張外字
            array(0xEF40,0xEF7E),array(0xEF80,0xEF9E), //  93区-NEC拡張外字
            array(0xEF9F,0xEFFC),                      //  94区-NEC拡張外字
            array(0xF040,0xF07E),array(0xF080,0xF09E), //  95区-ユーザ領域
            array(0xF09F,0xF0FC),                      //  96区-ユーザ領域
            array(0xF140,0xF17E),array(0xF180,0xF19E), //  97区-ユーザ領域
            array(0xF19F,0xF1FC),                      //  98区-ユーザ領域
            array(0xF240,0xF27E),array(0xF280,0xF29E), //  99区-ユーザ領域
            array(0xF29F,0xF2FC),                      // 100区-ユーザ領域
            array(0xF340,0xF37E),array(0xF380,0xF39E), // 101区-ユーザ領域
            array(0xF39F,0xF3FC),                      // 102区-ユーザ領域
            array(0xF440,0xF47E),array(0xF480,0xF49E), // 103区-ユーザ領域
            array(0xF49F,0xF4FC),                      // 104区-ユーザ領域
            array(0xF540,0xF57E),array(0xF580,0xF59E), // 105区-ユーザ領域
            array(0xF59F,0xF5FC),                      // 106区-ユーザ領域
            array(0xF640,0xF67E),array(0xF680,0xF69E), // 107区-ユーザ領域
            array(0xF69F,0xF6FC),                      // 108区-ユーザ領域
            array(0xF740,0xF77E),array(0xF780,0xF79E), // 109区-ユーザ領域
            array(0xF79F,0xF7FC),                      // 110区-ユーザ領域
            array(0xF840,0xF87E),array(0xF880,0xF89E), // 111区-ユーザ領域
            array(0xF89F,0xF8FC),                      // 112区-ユーザ領域
            array(0xF940,0xF97E),array(0xF980,0xF99E), // 113区-ユーザ領域
            array(0xF99F,0xF9FC),                      // 114区-ユーザ領域
            array(0xFA40,0xFA7E),array(0xFA80,0xFA9E), // 115区-IBM拡張漢字
            array(0xFA9F,0xFAFC),                      // 116区-IBM拡張漢字
            array(0xFB40,0xFB7E),array(0xFB80,0xFB9E), // 117区-IBM拡張漢字
            array(0xFB9F,0xFBFC),                      // 118区-IBM拡張漢字
            array(0xFC40,0xFC7E),array(0xFC80,0xFC9E), // 119区-IBM拡張漢字
            array(0xFC9F,0xFCFC),                      // 120区
        );

    $gaiji = array();
    foreach ($gaiji_ranges as $range) {
        $pre  = dechex($range[0]);
        $post = dechex($range[1]);
        $gaiji[]  = 
            '\x'.substr($pre,  0, 2).'\x'.substr($pre,  2, 2).'-' . 
            '\x'.substr($post, 0, 2).'\x'.substr($post, 2, 2);
    }
    $gaiji_regexp = '['.implode('', $gaiji).']';

    $regex_encoding = mb_regex_encoding();

    mb_regex_encoding('SJIS');
    $buf = mb_ereg_replace($gaiji_regexp, "\x81\xAC", $attribute);
    mb_regex_encoding($regex_encoding);

    return $buf;
}