str, $data->index, 2); $sub = self::utf16_charAt($sub, 0); $data->index += strlen($sub); $data->end = strlen($sub) <= 0; return self::utf16_ord($sub); } /** * @source http://blog.sarabande.jp/post/35970262740 * @param string $ch * @return bool|integer */ public static function utf16_ord($ch) { $length = strlen($ch); if (2 === $length) { return hexdec(bin2hex($ch)); } else if (4 === $length) { $w1 = $ch[0].$ch[1]; $w2 = $ch[2].$ch[3]; if ($w1 < "\xD8\x00" || "\xDF\xFF" < $w1 || $w2 < "\xDC\x00" || "\xDF\xFF" < $w2) { return false; } $w1 = (hexdec(bin2hex($w1)) & 0x3ff) << 10; $w2 = hexdec(bin2hex($w2)) & 0x3ff; return $w1 + $w2 + 0x10000; } return false; } /** * @param string $str * @param integer $num * * @return string */ public static function utf16_charAt($str, $num) { return mb_substr($str, $num, 1, 'UTF-16'); } /** * @param string $str * @return integer */ public static function utf16_strlen($str) { return mb_strlen($str, 'UTF-16'); } }