PageRenderTime 50ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/include/mb_emulator/mb-emulator.php

https://github.com/kaz6120/P_BLOG
PHP | 1447 lines | 1295 code | 139 blank | 13 comment | 238 complexity | d0e90c7a3a9d567ed820f92b2e5d97c0 MD5 | raw file
  1. <?php
  2. /* mb-emulator.php by Andy
  3. * email : webmaster@matsubarafamily.com
  4. *
  5. * license based on GPL(GNU General Public License)
  6. *
  7. * Ver.0.31 (2004/8/8)
  8. */
  9. include dirname(__FILE__).'/convert.table';
  10. include dirname(__FILE__).'/sjistouni.table';
  11. include dirname(__FILE__).'/unitosjis.table';
  12. $ini_file = parse_ini_file(dirname(__FILE__).'/mb-emulator.ini');
  13. $_language = $ini_file['language'];
  14. $_internal_encoding = $ini_file['internal-encoding'];
  15. $_lang_array = array (
  16. 'Japanese', 'ja', 'English', 'en', 'uni'
  17. );
  18. $_mb_encoding = array(
  19. 'AUTO' => 0,
  20. 'ASCII' => 0,
  21. 'EUC-JP' => 1,
  22. 'EUC' => 1,
  23. 'SJIS' => 2,
  24. 'SHIFT-JIS' => 2,
  25. 'SJIS-WIN' => 2,
  26. 'JIS' => 3,
  27. 'ISO-2022-JP' => 3,
  28. 'UTF-8' => 4,
  29. 'UTF8' => 4,
  30. 'UTF-16'=>5
  31. );
  32. if (!(mb_detect_order($ini_file['detect-order'])))
  33. $_detect_order = array ("ASCII", "JIS", "UTF-8", "EUC-JP", "SJIS");
  34. $sjis_match = "[\x81-\x9F,\xE0-\xFC]([\x40-\xFC])|[\x01-\x7F]|[\xA0-\xDF]";
  35. $euc_match = "[\xa1-\xfe]([\xa1-\xfe])|[\x01-\x7f]|\x8e([\xa0-\xdf])";
  36. $utf8_match = "[\x01-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]";
  37. function mb_language($language)
  38. {
  39. global $_language, $_lang_array;
  40. if ($language =='') {
  41. if ($_language == '') return FALSE;
  42. else return $_language;
  43. } else {
  44. foreach ($_lang_array as $element) {
  45. if ($element == $language) {
  46. $_language = $language;
  47. return TRUE;
  48. }
  49. }
  50. return FALSE;
  51. }
  52. }
  53. function mb_internal_encoding($encoding = '')
  54. {
  55. global $_internal_encoding;
  56. if ($encoding =='') {
  57. if ($_internal_encoding == '') return FALSE;
  58. else return $_internal_encoding;
  59. } else {
  60. $_internal_encoding = $encoding;
  61. return TRUE;
  62. }
  63. }
  64. function mb_convert_encoding( $str, $to_encoding, $from_encoding = '')
  65. {
  66. global $_internal_encoding, $_mb_encoding;
  67. $to_encoding = strtoupper($to_encoding);
  68. $from_encoding = mb_detect_encoding($str, $from_encoding);
  69. switch (isset($_mb_encoding[$from_encoding])) {
  70. case 1: //euc-jp
  71. switch($_mb_encoding[$to_encoding]) {
  72. case 2: //sjis
  73. return _euctosjis($str);
  74. case 3: //jis
  75. $str = _euctosjis($str);
  76. return _sjistojis($str);
  77. case 4: //utf8
  78. return _euctoutf8($str);
  79. case 5: //utf16
  80. $str = _euctoutf8($str);
  81. return _utf8toutf16($str);
  82. default:
  83. return $str;
  84. }
  85. case 2: //sjis
  86. switch($_mb_encoding[$to_encoding]) {
  87. case 1: //euc-jp
  88. return _sjistoeuc($str);
  89. case 3: //jis
  90. return _sjistojis($str);
  91. case 4: //utf8
  92. return _sjistoutf8($str);
  93. case 5: //utf16
  94. $str = _sjistoutf8($str);
  95. return _utf8toutf16($str);
  96. default:
  97. return $str;
  98. }
  99. case 3: //jis
  100. switch($_mb_encoding[$to_encoding]) {
  101. case 1: //euc-jp
  102. $str = _jistosjis($str);
  103. return _sjistoeuc($str);
  104. case 2: //sjis
  105. return _jistosjis($str);
  106. case 4: //utf8
  107. $str = _jistosjis($str);
  108. return _sjistoutf8($str);
  109. case 5: //utf16
  110. $str = _jistosjis($str);
  111. $str = _sjistoutf8($str);
  112. return _utf8toutf16($str);
  113. default:
  114. return $str;
  115. }
  116. case 4: //utf8
  117. switch($_mb_encoding[$to_encoding]) {
  118. case 1: //euc-jp
  119. return _utf8toeuc($str);
  120. case 2: //sjis
  121. return _utf8tosjis($str);
  122. case 3: //jis
  123. $str = _utf8tosjis($str);
  124. return _sjistojis($str);
  125. case 5: //utf16
  126. return _utf8toutf16($str);
  127. default:
  128. return $str;
  129. }
  130. default:
  131. return $str;
  132. }
  133. }
  134. function _get_encoding(&$str, $encoding)
  135. {
  136. global $_internal_encoding, $_mb_encoding;
  137. if ($encoding =='') {
  138. if ($_internal_encoding == '') {
  139. return mb_detect_encoding($str, mb_detect_order());
  140. } else {
  141. return $_internal_encoding;
  142. }
  143. }
  144. return strtoupper($encoding);
  145. }
  146. function _sjistoeuc(&$str)
  147. {
  148. global $sjis_match, $_sjistoeuc_byte1, $_sjistoeuc_byte2, $_sjistoeuc_byte1_shift;
  149. $max = preg_match_all("/$sjis_match/", $str, $allchars); // 文字の配列に分解
  150. $str_EUC = '';
  151. for ($i = 0; $i < $max; ++$i) {
  152. $num = ord($allchars[0][$i]); // 各文字の1バイト目を数値として取り出す
  153. if ($num2 = ord($allchars[1][$i])) { // 2バイト目がある場合
  154. $shift = $_sjistoeuc_byte1_shift[$num2];
  155. $str_EUC .= chr($_sjistoeuc_byte1[$num] + $shift)
  156. .chr($_sjistoeuc_byte2[$shift][$num2]);
  157. } elseif ($num <= 0x7F) {//英数字
  158. $str_EUC .= chr($num);
  159. } else { //半角カナ
  160. $str_EUC .= chr(0x8E).chr($num);
  161. }
  162. }
  163. return $str_EUC;
  164. }
  165. function _euctosjis(&$str)
  166. {
  167. global $euc_match, $_euctosjis_byte1, $_euctosjis_byte2;
  168. $max = preg_match_all("/$euc_match/", $str, $allchars); // 文字の配列に分解
  169. $str_SJIS = '';
  170. for ($i = 0; $i < $max; ++$i) {
  171. $num = ord($allchars[0][$i]); // 各文字の1バイト目を数値として取り出す
  172. if ($num2 = ord($allchars[1][$i])) { // 漢字の場合
  173. $str_SJIS .= chr($_euctosjis_byte1[$num]);
  174. if ($num & 1)
  175. $str_SJIS .= chr($_euctosjis_byte2[0][$num2]);
  176. else
  177. $str_SJIS .= chr($_euctosjis_byte2[1][$num2]);
  178. } elseif ($num3 = ord($allchars[2][$i])) {//半角カナ
  179. $str_SJIS .= chr($num3);
  180. } else { //英数字
  181. $str_SJIS .= chr($num);
  182. }
  183. }
  184. return $str_SJIS;
  185. }
  186. function _sjistojis(&$str)
  187. {
  188. global $sjis_match, $_sjistoeuc_byte1, $_sjistoeuc_byte2, $_sjistoeuc_byte1_shift;
  189. $max = preg_match_all("/$sjis_match/", $str, $allchars); // 文字の配列に分解
  190. $str_JIS = '';
  191. $mode = 0; // 英数
  192. for ($i = 0; $i < $max; ++$i) {
  193. $num = ord($allchars[0][$i]); // 各文字の1バイト目を数値として取り出す
  194. if ($num2 = ord($allchars[1][$i])) { // 2バイト目がある場合
  195. if ($mode != 1) {
  196. $mode = 1;
  197. $str_JIS .= chr(0x1b).'$B';
  198. }
  199. $shift = $_sjistoeuc_byte1_shift[$num2];
  200. $str_JIS .= chr(($_sjistoeuc_byte1[$num] + $shift) & 0x7F)
  201. .chr($_sjistoeuc_byte2[$shift][$num2] & 0x7F);
  202. } elseif ($num > 0x80) {//半角カナ
  203. if ($mode != 2) {
  204. $mode = 2;
  205. $str_JIS .= chr(0x1B).'(I';
  206. }
  207. $str_JIS .= chr($num & 0x7F);
  208. } else {//半角英数
  209. if ($mode != 0) {
  210. $mode = 0;
  211. $str_JIS .= chr(0x1B).'(B';
  212. }
  213. $str_JIS .= chr($num);
  214. }
  215. }
  216. if ($mode != 0) {
  217. $str_JIS .= chr(0x1B).'(B';
  218. }
  219. return $str_JIS;
  220. }
  221. function _sub_jtosj($match)
  222. {
  223. global $_euctosjis_byte1, $_euctosjis_byte2;
  224. $num = ord($match[0]);
  225. $num2 = ord($match[1]);
  226. $s = chr($_euctosjis_byte1[$num | 0x80]);
  227. if ($num & 1) {
  228. $s .= chr($_euctosjis_byte2[0][$num2 | 0x80]);
  229. } else {
  230. $s .= chr($_euctosjis_byte2[1][$num2 | 0x80]);
  231. }
  232. return $s;
  233. }
  234. function _jistosjis(&$str)
  235. {
  236. global $_euctosjis_byte1, $_euctosjis_byte2;
  237. $jis_match = "(?:^|\x1b\(B)([^\x1b]*)|\x1b$B([^\x1b]*)|\x1b\(I([^\x1b]*)";
  238. $max = preg_match_all("/$jis_match/", $str, $allchunks, PREG_SET_ORDER); // 文字種ごとの配列に分解
  239. $st = '';
  240. for ($i = 0; $i < $max; ++$i) {
  241. if (ord($allchunks[$i][1])) { //英数にマッチ
  242. $st .= $allchunks[$i][1];
  243. } elseif (ord($allchunks[$i][2])) { //漢字にマッチ
  244. $tmp = substr($allchunks[$i][0], 3, strlen($allchunks[$i][0]));
  245. $st .= preg_replace_callback("/.(.)/","_sub_jtosj", $tmp);
  246. } elseif (ord($allchunks[$i][3])) { //半角カナにマッチ
  247. $st .= preg_replace("/./e","chr(ord['$1'] | 0x80);",$allchunks[$i][3]);
  248. }
  249. }
  250. return $st;
  251. }
  252. function _ucs2utf8($uni)
  253. {
  254. if ($uni <= 0x7f)
  255. return chr($uni);
  256. elseif ($uni <= 0x7ff) {
  257. $y = ($uni >> 6) & 0x1f;
  258. $x = $uni & 0x3f;
  259. return chr(0xc0 | $y).chr(0x80 | $x);
  260. } else {
  261. $z = ($uni >> 12) & 0x0f;
  262. $y = ($uni >> 6) & 0x3f;
  263. $x = $uni & 0x3f;
  264. return chr(0xe0 | $z).chr(0x80 | $y).chr(0x80 | $x);
  265. }
  266. }
  267. function _sjistoutf8(&$str)
  268. {
  269. global $sjis_match, $sjistoucs2;
  270. $st = '';
  271. $max = preg_match_all("/$sjis_match/", $str, $allchars); // 文字の配列に分解
  272. for ($i = 0; $i < $max; ++$i) {
  273. $num = ord($allchars[0][$i]); // 各文字の1バイト目を数値として取り出す
  274. if ($num2 = ord($allchars[1][$i])) { // 2バイト目がある場合
  275. $ucs2 = $sjistoucs2[($num << 8) | $num2];
  276. $st .= _ucs2utf8($ucs2);
  277. } elseif ($num > 0x80) {//半角カナ
  278. $st .= _ucs2utf8(0xfec0 + $num);
  279. } else {//半角英数
  280. $st .= chr($num);
  281. }
  282. }
  283. return $st;
  284. }
  285. function _utf8ucs2($st)
  286. {
  287. $num = ord($st);
  288. if (!($num & 0x80)) //1byte
  289. return $num;
  290. elseif (($num & 0xe0) == 0xc0) {//2bytes
  291. $num2 = ord(substr($st, 1,1));
  292. return (($num & 0x1f) << 6) | ($num2 & 0x3f);
  293. } else { //3bytes
  294. $num2 = ord(substr($st, 1,1));
  295. $num3 = ord(substr($st, 2,1));
  296. return (($num & 0x0f) << 12) | (($num2 & 0x3f) << 6) | ($num3 & 0x3f);
  297. }
  298. }
  299. function _utf8tosjis(&$str)
  300. {
  301. global $utf8_match, $ucs2tosjis;
  302. $st = '';
  303. $max = preg_match_all("/$utf8_match/", $str, $allchars); // 文字の配列に分解
  304. for ($i = 0; $i < $max; ++$i) {
  305. $num = _utf8ucs2($allchars[0][$i]); //ucs2の値を取り出す
  306. if ($num < 0x80)
  307. $st .= chr($num);
  308. elseif ((0xff61 <= $num) && ($num <= 0xff9f))
  309. $st .= chr($num - 0xfec0);
  310. else {
  311. $sjis = $ucs2tosjis[$num];
  312. $st .= chr($sjis >> 8) . chr($sjis & 0xff);
  313. }
  314. }
  315. return $st;
  316. }
  317. function _euctoutf8(&$str)
  318. {
  319. global $euc_match, $sjistoucs2, $_euctosjis_byte1, $_euctosjis_byte2;
  320. $st = '';
  321. $max = preg_match_all("/$euc_match/", $str, $allchars); // 文字の配列に分解
  322. for ($i = 0; $i < $max; ++$i) {
  323. $num = ord($allchars[0][$i]); // 各文字の1バイト目を数値として取り出す
  324. if ($num2 = ord($allchars[1][$i])) { // 2バイト目がある場合
  325. if ($num & 1)
  326. $sjis = ($_euctosjis_byte1[$num] << 8) | $_euctosjis_byte2[0][$num2];
  327. else
  328. $sjis = ($_euctosjis_byte1[$num] << 8) | $_euctosjis_byte2[1][$num2];
  329. $st .= _ucs2utf8($sjistoucs2[$sjis]);
  330. } elseif ($num3 = ord($allchars[2][$i])) {
  331. $st .= _ucs2utf8(0xfec0 + $num3);
  332. } else {//半角英数
  333. $st .= chr($num);
  334. }
  335. }
  336. return $st;
  337. }
  338. function _utf8toeuc(&$str)
  339. {
  340. global $utf8_match, $ucs2tosjis, $_sjistoeuc_byte1, $_sjistoeuc_byte2, $_sjistoeuc_byte1_shift;
  341. $st = '';
  342. $max = preg_match_all("/$utf8_match/", $str, $allchars); // 文字の配列に分解
  343. for ($i = 0; $i < $max; ++$i) {
  344. $num = _utf8ucs2($allchars[0][$i]); //ucs2の値を取り出す
  345. if ($num < 0x80)
  346. $st .= chr($num);
  347. elseif ((0xff61 <= $num) && ($num <= 0xff9f)) //半角カナ
  348. $st .= chr(0x8e) . chr($num - 0xfec0);
  349. else {
  350. $sjis = $ucs2tosjis[$num];
  351. $upper = $sjis >> 8;
  352. $lower = $sjis & 0xff;
  353. $shift = $_sjistoeuc_byte1_shift[$lower];
  354. $st .= chr($_sjistoeuc_byte1[$upper] + $shift)
  355. .chr($_sjistoeuc_byte2[$shift][$lower]);
  356. }
  357. }
  358. return $st;
  359. }
  360. function _utf8toutf16(&$str)
  361. {
  362. global $utf8_match;
  363. $st = '';
  364. $max = preg_match_all("/$utf8_match/", $str, $allchars); // 文字の配列に分解
  365. for ($i = 0; $i < $max; ++$i) {
  366. $num = _utf8ucs2($allchars[0][$i]); //ucs2の値を取り出す
  367. $st .= chr(($num >> 8) & 0xff).chr($num & 0xff);
  368. }
  369. return $st;
  370. }
  371. function sub_zenhan_EUC(&$str, $match) {
  372. global $alphanumeric_convert;
  373. $match = $match . "|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
  374. $max = preg_match_all("/$match/", $str, $chars);
  375. $str = '';
  376. for ($i = 0; $i < $max; ++$i) {
  377. if ($num = ord($chars[1][$i])) //全角にマッチングした場合
  378. $str .= chr(array_search($chars[1][$i], $alphanumeric_convert));
  379. // $str .= chr($num & 0x7F);
  380. else
  381. $str .= $chars[0][$i];
  382. }
  383. }
  384. function sub_hanzen_EUC(&$str, $match) {
  385. global $alphanumeric_convert;
  386. $match = $match . "|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
  387. $max = preg_match_all("/$match/", $str, $chars);
  388. $str = '';
  389. for ($i = 0; $i < $max; ++$i) {
  390. if ($num = ord($chars[1][$i])) //半角にマッチングした場合
  391. $str .= $alphanumeric_convert[$num];
  392. else
  393. $str .= $chars[0][$i];
  394. }
  395. }
  396. function alpha_zenhan_EUC(&$str) {
  397. sub_zenhan_EUC($str, "(\xA3[\xC1-\xFA])");
  398. }
  399. function alpha_hanzen_EUC(&$str) {
  400. sub_hanzen_EUC($str, "([\x41-\x5A,\x61-\x7A])");
  401. }
  402. function num_zenhan_EUC(&$str) {
  403. sub_zenhan_EUC($str, "(\xA3[\xB0-\xB9])");
  404. }
  405. function num_hanzen_EUC(&$str) {
  406. sub_hanzen_EUC($str, "([\x30-\x39])");
  407. }
  408. function alphanum_zenhan_EUC(&$str) {
  409. sub_zenhan_EUC($str, "(\xa1[\xa4,\xa5,\xa7-\xaa,\xb0,\xb2,\xbf,\xc3,\xca,\xcb,\xce-\xd1,\xdc,\xdd,\xe1,\xe3,\xe4,\xf0,\xf3-\xf7]|\xA3[\xC1-\xFA]|\xA3[\xB0-\xB9])");
  410. }
  411. function alphanum_hanzen_EUC(&$str) {
  412. sub_hanzen_EUC($str, "([\\\x21,\\\x23-\\\x26,\\\x28-\\\x5B,\\\x5D-\\\x7D])");
  413. }
  414. function space_zenhan_EUC(&$str) {
  415. sub_zenhan_EUC($str, "(\xA1\xA1)");
  416. }
  417. function space_hanzen_EUC(&$str) {
  418. sub_hanzen_EUC($str, "(\x20)");
  419. }
  420. function katakana_zenhan_EUC(&$str) {
  421. global $kana_zenhan_convert, $special_zenhan_convert;
  422. $match = "\xa5([\xa1-\xf4])|\xa1([\xa2,\xa3,\xa6,\xab,\xac,\xbc,\xd6,\xd7])|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
  423. $max = preg_match_all("/$match/", $str, $chars);
  424. $str = '';
  425. for ($i = 0; $i < $max; ++$i) {
  426. if ($num = ord($chars[1][$i])) //カナにマッチングした場合
  427. $str .= chr(0x8e) . $kana_zenhan_convert[$num];
  428. elseif ($num = ord($chars[2][$i])) //半角変換可能な特殊文字にマッチした場合
  429. $str .= chr(0x8e) . $special_zenhan_convert[$num];
  430. else
  431. $str .= $chars[0][$i];
  432. }
  433. }
  434. function hiragana_zenhan_EUC(&$str) {
  435. global $kana_zenhan_convert, $special_zenhan_convert;
  436. $match = "\xa4([\xa1-\xf4])|\xa1([\xa2,\xa3,\xa6,\xab,\xac,\xbc,\xd6,\xd7])|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
  437. $max = preg_match_all("/$match/", $str, $chars);
  438. $str = '';
  439. for ($i = 0; $i < $max; ++$i) {
  440. if ($num = ord($chars[1][$i])) //かなにマッチングした場合
  441. $str .= chr(0x8e) . $kana_zenhan_convert[$num];
  442. elseif ($num = ord($chars[2][$i])) //半角変換可能な特殊文字にマッチした場合
  443. $str .= chr(0x8e) . $special_zenhan_convert[$num];
  444. else
  445. $str .= $chars[0][$i];
  446. }
  447. }
  448. function katakana_hanzen1_EUC(&$str) { //濁点の統合をする方
  449. global $kana_zenhan_convert, $special_zenhan_convert;
  450. $match = "\x8e((?:[\xb3,\xb6-\xc4,\xca-\xce]\x8e\xde)|(?:[\xca-\xce]\x8e\xdf))|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e([\xa1-\xdf])";
  451. //濁点や半濁点は一緒にマッチング
  452. $max = preg_match_all("/$match/", $str, $chars);
  453. $str = '';
  454. for ($i = 0; $i < $max; ++$i) {
  455. if ($chars[1][$i]) //濁音,半濁音にマッチングした場合
  456. $str .= chr(0xa5).chr(array_search($chars[1][$i], $kana_zenhan_convert));
  457. elseif ($chars[2][$i]) //その他の半角カナにマッチ
  458. if ($num = array_search($chars[2][$i], $kana_zenhan_convert))
  459. $str .= chr(0xa5).chr($num);
  460. else
  461. $str .= chr(0xa1).chr(array_search($chars[2][$i], $special_zenhan_convert));
  462. else
  463. $str .= $chars[0][$i];
  464. }
  465. }
  466. function hiragana_hanzen1_EUC(&$str) { //濁点の統合をする方
  467. global $kana_zenhan_convert, $special_zenhan_convert;
  468. $match = "\x8e((?:[\xb6-\xc4,\xca-\xce]\x8e\xde)|(?:[\xca-\xce]\x8e\xdf))|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e([\xa1-\xdf])";
  469. //濁点や半濁点は一緒にマッチング
  470. $max = preg_match_all("/$match/", $str, $chars);
  471. $str = '';
  472. for ($i = 0; $i < $max; ++$i) {
  473. if ($chars[1][$i]) //濁音,半濁音にマッチングした場合
  474. $str .= chr(0xa4).chr(array_search($chars[1][$i], $kana_zenhan_convert));
  475. elseif ($chars[2][$i]) //その他の半角カナにマッチ
  476. if ($num = array_search($chars[2][$i], $kana_zenhan_convert))
  477. $str .= chr(0xa4).chr($num);
  478. else
  479. $str .= chr(0xa1).chr(array_search($chars[2][$i], $special_zenhan_convert));
  480. else
  481. $str .= $chars[0][$i];
  482. }
  483. }
  484. function katakana_hanzen2_EUC(&$str) { //濁点の統合をしない方
  485. global $kana_zenhan_convert, $special_zenhan_convert;
  486. $match = "[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e([\xa1-\xdf])";
  487. $max = preg_match_all("/$match/", $str, $chars);
  488. $str = '';
  489. for ($i = 0; $i < $max; ++$i) {
  490. if ($chars[1][$i]) //半角カナにマッチ
  491. if ($num = array_search($chars[1][$i], $kana_zenhan_convert))
  492. $str .= chr(0xa5).chr($num);
  493. else
  494. $str .= chr(0xa1).chr(array_search($chars[1][$i], $special_zenhan_convert));
  495. else
  496. $str .= $chars[0][$i];
  497. }
  498. }
  499. function hiragana_hanzen2_EUC(&$str) { //濁点の統合をしない方
  500. global $kana_zenhan_convert, $special_zenhan_convert;
  501. $match = "[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e([\xa1-\xdf])";
  502. $max = preg_match_all("/$match/", $str, $chars);
  503. $str = '';
  504. for ($i = 0; $i < $max; ++$i) {
  505. if ($chars[1][$i]) //半角カナにマッチ
  506. if ($num = array_search($chars[1][$i], $kana_zenhan_convert))
  507. $str .= chr(0xa4).chr($num);
  508. else
  509. $str .= chr(0xa1).chr(array_search($chars[1][$i], $special_zenhan_convert));
  510. else
  511. $str .= $chars[0][$i];
  512. }
  513. }
  514. function katakana_hiragana_EUC(&$str) {
  515. $match = "\xa5([\xa1-\xf3])|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
  516. $max = preg_match_all("/$match/", $str, $chars);
  517. $str = '';
  518. for ($i = 0; $i < $max; ++$i) {
  519. if ($num = ord($chars[1][$i])) //カナにマッチングした場合
  520. $str .= chr(0xa4) . chr($num);
  521. else
  522. $str .= $chars[0][$i];
  523. }
  524. }
  525. function hiragana_katakana_EUC(&$str) {
  526. $match = "\xa4([\xa1-\xf4])|[\xa1-\xfe][\xa1-\xfe]|[\x01-\x7f]|\x8e[\xa0-\xdf]";
  527. $max = preg_match_all("/$match/", $str, $chars);
  528. $str = '';
  529. for ($i = 0; $i < $max; ++$i) {
  530. if ($num = ord($chars[1][$i])) //カナにマッチングした場合
  531. $str .= chr(0xa5) . chr($num);
  532. else
  533. $str .= $chars[0][$i];
  534. }
  535. }
  536. function mb_convert_kana( $str, $option='KV', $encoding = '')
  537. {
  538. $encoding = mb_detect_encoding($str, $encoding);
  539. $str = mb_convert_encoding($str, 'EUC-JP', $encoding);
  540. if (strstr($option, "r")) alpha_zenhan_EUC($str);
  541. if (strstr($option, "R")) alpha_hanzen_EUC($str);
  542. if (strstr($option, "n")) num_zenhan_EUC($str);
  543. if (strstr($option, "N")) num_hanzen_EUC($str);
  544. if (strstr($option, "a")) alphanum_zenhan_EUC($str);
  545. if (strstr($option, "A")) alphanum_hanzen_EUC($str);
  546. if (strstr($option, "s")) space_zenhan_EUC($str);
  547. if (strstr($option, "S")) space_hanzen_EUC($str);
  548. if (strstr($option, "k")) katakana_zenhan_EUC($str);
  549. if (strstr($option, "K")) {
  550. if (strstr($option, "V"))
  551. katakana_hanzen1_EUC($str);
  552. else
  553. katakana_hanzen2_EUC($str);
  554. }
  555. if (strstr($option, "H")) {
  556. if (strstr($option, "V"))
  557. hiragana_hanzen1_EUC($str);
  558. else
  559. hiragana_hanzen2_EUC($str);
  560. }
  561. if (strstr($option, "h")) hiragana_zenhan_EUC($str);
  562. if (strstr($option, "c")) katakana_hiragana_EUC($str);
  563. if (strstr($option, "C")) hiragana_katakana_EUC($str);
  564. $str = mb_convert_encoding($str, $encoding, 'EUC-JP');
  565. return $str;
  566. }
  567. function mb_send_mail($to, $subject, $message , $additional_headers, $additional_parameter)
  568. {
  569. $subject ='=?iso-2022-jp?B?' . base64_encode($subject) . '?=';
  570. $additional_headers .=
  571. "\r\nMime-Version: 1.0\r\nContent-Type: text/plain; charset=ISO-2022-JP\r\nContent-Transfer-Encoding: 7bit";
  572. mail($to, $subject, $message, $additional_headers, $additional_parameter);
  573. }
  574. function mb_detect_order($encoding_list = '')
  575. {
  576. global $_detect_order, $_mb_encoding;
  577. if ($encoding_list) {
  578. if (is_string($encoding_list)) {
  579. $encoding_list = strtoupper($encoding_list);
  580. $encoding_list = split(', *', $encoding_list);
  581. }
  582. foreach($encoding_list as $encode)
  583. if (!array_key_exists($encode, $_mb_encoding)) return FALSE;
  584. $_detect_order = $encoding_list;
  585. return TRUE;
  586. }
  587. return $_detect_order;
  588. }
  589. function _is_Ascii(&$str)
  590. {
  591. return (!ereg("[\x80-\xFF]", $str) && !ereg("\x1B", $str));
  592. }
  593. function _is_JIS(&$str)
  594. {
  595. return (!ereg("[\x80-\xFF]", $str) && ereg("\x1B", $str));
  596. }
  597. function _is_SJIS(&$str)
  598. {
  599. $sjis_match =
  600. "[\x01-\x7F]|[\xA0-\xDF]|[\x81-\xFC][\x40-\xFC]";
  601. return (preg_match("/^($sjis_match)+$/", $str) == 1);
  602. }
  603. function _is_EUCJP(&$str)
  604. {
  605. $euc_match =
  606. "[\x01-\x7F]|\x8E[\xA0-\xDF]|\x8F[xA1-\xFE][\xA1-\xFE]|[\xA1-\xFE][\xA1-\xFE]";
  607. return (preg_match("/^($euc_match)+$/", $str) == 1);
  608. }
  609. function _is_UTF8(&$str)
  610. {
  611. $utf8_match =
  612. "[\x01-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF][\x80-\xBF]";
  613. return (preg_match("/^($utf8_match)+$/", $str) == 1);
  614. }
  615. function mb_detect_encoding( $str , $encoding_list = '')
  616. {
  617. global $_mb_encoding;
  618. if ($encoding_list == '')
  619. $encoding_list = mb_detect_order();
  620. if (!is_array($encoding_list)) {
  621. $encoding_list = strtoupper($encoding_list);
  622. if ($encoding_list == 'AUTO') {
  623. $encoding_list = mb_detect_order();
  624. } else {
  625. $encoding_list = split(', *', $encoding_list);
  626. }
  627. }
  628. $encoding_list = array("EUC-JP");
  629. foreach($encoding_list as $encode) {
  630. switch ($_mb_encoding[$encode]) {
  631. case 0 : //ascii
  632. if (_is_ASCII($str)) return 'ASCII';
  633. break;
  634. case 1 : //euc-jp
  635. if (_is_EUCJP($str)) return 'EUC-JP';
  636. break;
  637. case 2 : //shift-jis
  638. if (_is_SJIS($str)) return 'SJIS';
  639. break;
  640. case 3 : //jis
  641. if (_is_JIS($str)) return 'JIS';
  642. break;
  643. case 4 : //utf-8
  644. if (_is_UTF8($str)) return 'UTF-8';
  645. break;
  646. }
  647. }
  648. }
  649. function mb_strlen ( $str , $encoding='')
  650. {
  651. global $_mb_encoding, $euc_match, $utf8_match, $sjis_match;
  652. $encoding = _get_encoding($str, $encoding);
  653. switch ($_mb_encoding[$encoding]) {
  654. case 1 : //euc-jp
  655. return preg_match_all("/$euc_match/", $str, $arr);
  656. case 0 : //ascii
  657. case 4 : //utf-8
  658. return preg_match_all("/$utf8_match/", $str, $arr);
  659. case 2 : //shift-jis
  660. return preg_match_all("/$sjis_match/", $str, $arr);
  661. case 3 : //jis
  662. $str = mb_convert_encoding($str, 'SJIS', 'JIS');
  663. return preg_match_all("/$sjis_match/", $str, $arr);
  664. }
  665. }
  666. function mb_strwidth( $str, $encoding='')
  667. {
  668. global $_mb_encoding, $euc_match, $utf8_match, $sjis_match;
  669. $encoding = _get_encoding($str, $encoding);
  670. switch ($_mb_encoding[$encoding]) {
  671. case 1 : //euc-jp
  672. $max = $len = preg_match_all("/$euc_match/", $str, $arr);
  673. $len;
  674. for ($i=0; $i < $max; ++$i)
  675. if ($arr[1][$i]) ++$len;
  676. return $len;
  677. case 0 : //ascii
  678. case 4 : //utf-8
  679. $max = $len = preg_match_all("/$utf8_match/", $str, $arr);
  680. for ($i=0; $i < $max; ++$i) {
  681. $ucs2 = _utf8ucs2($arr[0][$i]);
  682. if (((0x2000 <= $ucs2) && ($ucs2 <= 0xff60)) || (0xffa0 <= $ucs2))
  683. ++$len;
  684. }
  685. return $len;
  686. case 2 : //shift-jis
  687. $max = $len = preg_match_all("/$sjis_match/", $str, $arr);
  688. for ($i=0; $i < $max; ++$i)
  689. if ($arr[1][$i]) ++$len;
  690. return $len;
  691. case 3 : //jis
  692. $str = mb_convert_encoding($str, 'SJIS', 'JIS');
  693. $max = $len = preg_match_all("/$sjis_match/", $str, $arr);
  694. for ($i=0; $i < $max; ++$i)
  695. if ($arr[1][$i]) ++$len;
  696. return $len;
  697. }
  698. }
  699. function mb_strimwidth( $str, $start, $width, $trimmarker , $encoding = '')
  700. {
  701. global $_mb_encoding, $euc_match, $utf8_match, $sjis_match;
  702. $encoding = _get_encoding($str, $encoding);
  703. $str = mb_substr($str, $start, 'notnumber', $encoding);
  704. if (($len = mb_strwidth($str,$encoding)) <= $width)
  705. return $str;
  706. $trimwidth = mb_strwidth($trimmarker,$encoding);
  707. $width -= $trimwidth;
  708. if ($width <= 0) return $trimmarker;
  709. switch ($_mb_encoding[$encoding]) {
  710. case 1 : //euc-jp
  711. preg_match_all("/$euc_match/", $str, $arr);
  712. $i = 0;
  713. while(TRUE) {
  714. if ($arr[1][$i])
  715. $width -= 2;
  716. else
  717. --$width;
  718. if ($width<0) break;
  719. ++$i;
  720. }
  721. $arr[0] = array_slice($arr[0], 0, $i);
  722. return implode("", $arr[0]).$trimmarker;
  723. case 0 : //ascii
  724. case 4 : //utf-8
  725. preg_match_all("/$utf8_match/", $str, $arr);
  726. $i = 0;
  727. while(TRUE) {
  728. $ucs2 = _utf8ucs2($arr[0][$i]);
  729. if (((0x2000 <= $ucs2) && ($ucs2 <= 0xff60)) || (0xffa0 <= $ucs2))
  730. $width -= 2;
  731. else
  732. --$width;
  733. if ($width<0) break;
  734. ++$i;
  735. }
  736. $arr[0] = array_slice($arr[0], 0, $i);
  737. return implode("", $arr[0]).$trimmarker;
  738. case 2 : //shift-jis
  739. preg_match_all("/$sjis_match/", $str, $arr);
  740. $i = 0;
  741. while(TRUE) {
  742. if ($arr[1][$i])
  743. $width -= 2;
  744. else
  745. --$width;
  746. if ($width<0) break;
  747. ++$i;
  748. }
  749. $arr[0] = array_slice($arr[0], 0, $i);
  750. return implode("", $arr[0]).$trimmarker;
  751. case 3 : //jis
  752. $str = mb_convert_encoding($str, 'SJIS', 'JIS');
  753. $trimmarker = mb_convert_encoding($trimmarker, 'SJIS', 'JIS');
  754. preg_match_all("/$sjis_match/", $str, $arr);
  755. $i = 0;
  756. while(TRUE) {
  757. if ($arr[1][$i])
  758. $width -= 2;
  759. else
  760. --$width;
  761. if ($width<0) break;
  762. ++$i;
  763. }
  764. $arr[0] = array_slice($arr[0], 0, $i);
  765. return mb_convert_encoding(implode("", $arr[0]).$trimmarker,'JIS','SJIS');
  766. }
  767. }
  768. function mb_substr ( $str, $start , $length='notnumber' , $encoding='')
  769. {
  770. global $_mb_encoding, $euc_match, $utf8_match, $sjis_match;
  771. $encoding = _get_encoding($str, $encoding);
  772. switch ($_mb_encoding[$encoding]) {
  773. case 1 : //euc-jp
  774. preg_match_all("/$euc_match/", $str, $arr);
  775. break;
  776. case 0 : //ascii
  777. case 4 : //utf-8
  778. preg_match_all("/$utf8_match/", $str, $arr);
  779. break;
  780. case 2 : //shift-jis
  781. preg_match_all("/$sjis_match/", $str, $arr);
  782. break;
  783. case 3 : //jis
  784. $str = mb_convert_encoding($str, 'SJIS', 'JIS');
  785. preg_match_all("/$sjis_match/", $str, $arr);
  786. }
  787. if (is_int($length))
  788. $arr[0] = array_slice($arr[0], $start, $length);
  789. else
  790. $arr[0] = array_slice($arr[0], $start);
  791. $str = implode("", $arr[0]);
  792. if ($_mb_encoding[$encoding] == 3)
  793. $str = mb_convert_encoding($str, 'JIS', 'SJIS');
  794. return $str;
  795. }
  796. function _sub_strcut($arr, $start, $length) {
  797. $max = count($arr);
  798. $s = ''; $counter = 0;
  799. for ($i = 0; $i < $max; ++$i) {
  800. $counter += strlen($arr[0][$i]);
  801. if ($counter > $start) {
  802. if ($length == 0) {
  803. for ($j = $i; $j < $max; ++$j)
  804. $s .= $arr[0][$j];
  805. return $s;
  806. }
  807. for ($j = $i, $len = 0; $j < $max; ++$j) {
  808. $len += strlen($arr[0][$j]);
  809. if ($len <= $length)
  810. $s .= $arr[0][$j];
  811. }
  812. return $s;
  813. }
  814. }
  815. return $s;
  816. }
  817. function mb_strcut ( $str, $start , $length=0 , $encoding = '')
  818. {
  819. global $_mb_encoding, $euc_match, $utf8_match, $sjis_match;
  820. $encoding = _get_encoding($str, $encoding);
  821. switch ($_mb_encoding[$encoding]) {
  822. case 1 : //euc-jp
  823. preg_match_all("/$euc_match/", $str, $arr);
  824. return _sub_strcut($arr, $start, $length);
  825. case 0 : //ascii
  826. return substr($str, $start, $length);
  827. case 4 : //utf-8
  828. preg_match_all("/$utf8_match/", $str, $arr);
  829. return _sub_strcut($arr, $start, $length);
  830. case 2 : //shift-jis
  831. preg_match_all("/$sjis_match/", $str, $arr);
  832. return _sub_strcut($arr, $start, $length);
  833. case 3 : //jis
  834. $str = mb_convert_encoding($str, 'SJIS', 'JIS');
  835. preg_match_all("/$sjis_match/", $str, $arr);
  836. $sub = _sub_strcut($arr, $start, $length);
  837. return mb_convert_encoding($sub, 'JIS', 'SJIS');
  838. }
  839. }
  840. function _sub_strrpos($ar_haystack, $ar_needle)
  841. {
  842. $max_h = count($ar_haystack) - 1;
  843. $max_n = count($ar_needle) - 1;
  844. for ($i = $max_h; $i >= $max_n; --$i) {
  845. if ($ar_haystack[$i] == $ar_needle[$max_n]) {
  846. $match = TRUE;
  847. for ($j = 1; $j <= $max_n; ++$j)
  848. if ($ar_haystack[$i-$j] != $ar_needle[$max_n-$j]) {
  849. $match = FALSE;
  850. break;
  851. }
  852. if ($match) return $i - $max_n;
  853. }
  854. }
  855. return FALSE;
  856. }
  857. function mb_strrpos ( $haystack, $needle , $encoding = '')
  858. {
  859. global $_mb_encoding, $euc_match, $utf8_match, $sjis_match;
  860. $encoding = _get_encoding($haystack, $encoding);
  861. switch ($_mb_encoding[$encoding]) {
  862. case 1 : //euc-jp
  863. preg_match_all("/$euc_match/", $haystack, $ar_h);
  864. preg_match_all("/$euc_match/", $needle, $ar_n);
  865. return _sub_strrpos($ar_h[0], $ar_n[0]);
  866. case 0 : //ascii
  867. case 4 : //utf-8
  868. preg_match_all("/$utf8_match/", $haystack, $ar_h);
  869. preg_match_all("/$utf8_match/", $needle, $ar_n);
  870. return _sub_strrpos($ar_h[0], $ar_n[0]);
  871. case 2 : //shift-jis
  872. preg_match_all("/$sjis_match/", $haystack, $ar_h);
  873. preg_match_all("/$sjis_match/", $needle, $ar_n);
  874. return _sub_strrpos($ar_h[0], $ar_n[0]);
  875. case 3 : //jis
  876. $haystack = mb_convert_encoding($haystack, 'SJIS', 'JIS');
  877. $needle = mb_convert_encoding($needle, 'SJIS', 'JIS');
  878. preg_match_all("/$sjis_match/", $haystack, $ar_h);
  879. preg_match_all("/$sjis_match/", $needle, $ar_n);
  880. return _sub_strrpos($ar_h[0], $ar_n[0]);
  881. }
  882. }
  883. function _sub_strpos($ar_haystack, $ar_needle, $offset)
  884. {
  885. $max_n = count($ar_needle) - 1;
  886. $max_h = count($ar_haystack) - count($ar_needle);
  887. for ($i = $offset; $i <= $max_h; ++$i) {
  888. for ($j = 0; $j <= $max_n; ++$j) {
  889. $match = TRUE;
  890. if ($ar_haystack[$i+$j] != $ar_needle[$j]) {
  891. $match = FALSE;
  892. break;
  893. }
  894. }
  895. if ($match) return $i;
  896. }
  897. return FALSE;
  898. }
  899. function mb_strpos ( $haystack, $needle , $offset = 0, $encoding = '')
  900. {
  901. global $_mb_encoding, $euc_match, $utf8_match, $sjis_match;
  902. $encoding = _get_encoding($haystack, $encoding);
  903. switch ($_mb_encoding[$encoding]) {
  904. case 1 : //euc-jp
  905. preg_match_all("/$euc_match/", $haystack, $ar_h);
  906. preg_match_all("/$euc_match/", $needle, $ar_n);
  907. return _sub_strpos($ar_h[0], $ar_n[0], $offset);
  908. case 0 : //ascii
  909. case 4 : //utf-8
  910. preg_match_all("/$utf8_match/", $haystack, $ar_h);
  911. preg_match_all("/$utf8_match/", $needle, $ar_n);
  912. return _sub_strpos($ar_h[0], $ar_n[0], $offset);
  913. case 2 : //shift-jis
  914. preg_match_all("/$sjis_match/", $haystack, $ar_h);
  915. preg_match_all("/$sjis_match/", $needle, $ar_n);
  916. return _sub_strpos($ar_h[0], $ar_n[0], $offset);
  917. case 3 : //jis
  918. $haystack = mb_convert_encoding($haystack, 'SJIS', 'JIS');
  919. $needle = mb_convert_encoding($needle, 'SJIS', 'JIS');
  920. preg_match_all("/$sjis_match/", $haystack, $ar_h);
  921. preg_match_all("/$sjis_match/", $needle, $ar_n);
  922. return _sub_strpos($ar_h[0], $ar_n[0], $offset);
  923. }
  924. }
  925. function _sub_substr_count($ar_haystack, $ar_needle)
  926. {
  927. $matches = 0;
  928. $max_n = count($ar_needle) - 1;
  929. $max_h = count($ar_haystack) - count($ar_needle);
  930. for ($i = 0; $i <= $max_h; ++$i) {
  931. for ($j = 0; $j <= $max_n; ++$j) {
  932. $match = TRUE;
  933. if ($ar_haystack[$i+$j] != $ar_needle[$j]) {
  934. $match = FALSE;
  935. break;
  936. }
  937. }
  938. if ($match) ++$matches;
  939. }
  940. return $matches;
  941. }
  942. function mb_substr_count($haystack, $needle , $encoding = '')
  943. {
  944. global $_mb_encoding, $euc_match, $utf8_match, $sjis_match;
  945. $encoding = _get_encoding($haystack, $encoding);
  946. switch ($_mb_encoding[$encoding]) {
  947. case 1 : //euc-jp
  948. preg_match_all("/$euc_match/", $haystack, $ar_h);
  949. preg_match_all("/$euc_match/", $needle, $ar_n);
  950. return _sub_substr_count($ar_h[0], $ar_n[0]);
  951. case 0 : //ascii
  952. case 4 : //utf-8
  953. preg_match_all("/$utf8_match/", $haystack, $ar_h);
  954. preg_match_all("/$utf8_match/", $needle, $ar_n);
  955. return _sub_substr_count($ar_h[0], $ar_n[0]);
  956. case 2 : //shift-jis
  957. preg_match_all("/$sjis_match/", $haystack, $ar_h);
  958. preg_match_all("/$sjis_match/", $needle, $ar_n);
  959. return _sub_substr_count($ar_h[0], $ar_n[0]);
  960. case 3 : //jis
  961. $haystack = mb_convert_encoding($haystack, 'SJIS', 'JIS');
  962. $needle = mb_convert_encoding($needle, 'SJIS', 'JIS');
  963. preg_match_all("/$sjis_match/", $haystack, $ar_h);
  964. preg_match_all("/$sjis_match/", $needle, $ar_n);
  965. return _sub_substr_count($ar_h[0], $ar_n[0]);
  966. }
  967. }
  968. /******************
  969. mb_convert_variables
  970. *******************/
  971. if (!$ini_file['convert-variables-arrayonly']) {
  972. function mb_convert_variables($to_encoding, $from_encoding, $s1, $s2='',$s3='',$s4='',$s5='',$s6='',$s7='', $s8='',$s9='', $s10='')
  973. {
  974. if (is_array($s1)) {
  975. $st = '';
  976. foreach($s1 as $s) $st .= $s;
  977. if (!($encode = mb_detect_encoding($st, $from_encoding)))
  978. return FALSE;
  979. reset($s1);
  980. while (list ($key, $val) = each ($s1)) {
  981. $s1[$key] = mb_convert_encoding($val, $to_encoding, $encode);
  982. }
  983. return $encode;
  984. }
  985. $st = $s1.$s2.$s3.$s4.$s5.$s6.$s7.$s8.$s9.$s10;
  986. if (!($encode = mb_detect_encoding($st, $from_encoding)))
  987. return FALSE;
  988. $s1 = mb_convert_encoding($s1, $to_encoding, $encode);
  989. $s2 = mb_convert_encoding($s2, $to_encoding, $encode);
  990. $s3 = mb_convert_encoding($s3, $to_encoding, $encode);
  991. $s4 = mb_convert_encoding($s4, $to_encoding, $encode);
  992. $s5 = mb_convert_encoding($s5, $to_encoding, $encode);
  993. $s6 = mb_convert_encoding($s6, $to_encoding, $encode);
  994. $s7 = mb_convert_encoding($s7, $to_encoding, $encode);
  995. $s8 = mb_convert_encoding($s8, $to_encoding, $encode);
  996. $s9 = mb_convert_encoding($s9, $to_encoding, $encode);
  997. $s10 = mb_convert_encoding($s10, $to_encoding, $encode);
  998. return $encode;
  999. }
  1000. } else {
  1001. function mb_convert_variables($to_encoding, $from_encoding, &$arr)
  1002. {
  1003. $st = '';
  1004. foreach($arr as $s) $st .= $s;
  1005. if (!($encode = mb_detect_encoding($st, $from_encoding)))
  1006. return FALSE;
  1007. reset($arr);
  1008. while (list ($key, $val) = each ($arr)) {
  1009. $arr[$key] = mb_convert_encoding($val, $to_encoding, $encode);
  1010. }
  1011. return $encode;
  1012. }
  1013. }
  1014. function mb_preferred_mime_name ($encoding)
  1015. {
  1016. global $_mb_encoding;
  1017. $encoding = strtoupper($encoding);
  1018. switch ($_mb_encoding[$encoding]) {
  1019. case 0 : //ascii
  1020. return 'US-ASCII';
  1021. case 1 : //euc-jp
  1022. return 'EUC-JP';
  1023. case 2 : //shift-jis
  1024. return 'Shift_JIS';
  1025. case 3 : //jis
  1026. return 'ISO-2022-JP';
  1027. case 4 : //utf-8
  1028. return 'UTF-8';
  1029. }
  1030. }
  1031. function mb_decode_mimeheader($str)
  1032. {
  1033. $lines = preg_split("/(\r\n|\r|\n)( *)/", $str);
  1034. $s = '';
  1035. foreach ($lines as $line) {
  1036. if ($line != "") {
  1037. $line = preg_replace("/<[\w\-+\.]+\@[\w\-+\.]+>/","", $line); //メール・アドレス部を消す
  1038. $matches = preg_split("/=\?([^?]+)\?(B|Q)\?([^?]+)\?=/", $line, -1, PREG_SPLIT_DELIM_CAPTURE);
  1039. for ($i = 0; $i < count($matches)-1; $i+=4) {
  1040. if (!preg_match("/^[ \t\r\n]*$/", $matches[$i]))
  1041. $s .= $matches[$i];
  1042. if ($matches[$i+2] == 'B')
  1043. $s .= mb_convert_encoding(base64_decode($matches[$i+3]),
  1044. mb_internal_encoding(), $matches[$i+1]);
  1045. else
  1046. $s .= mb_convert_encoding(quoted_printable_decode($matches[$i+3]),
  1047. mb_internal_encoding(), $matches[$i+1]);
  1048. }
  1049. if (!preg_match("/^[ \t\r\n]*$/", $matches[$i]))
  1050. $s .= $matches[$i];
  1051. }
  1052. }
  1053. return $s;
  1054. }
  1055. function _sub_qponechar($str, &$len)
  1056. {
  1057. $all = unpack("C*", $str);
  1058. $s = ''; $len = 0;
  1059. foreach($all as $char) {
  1060. if (((ord('A') <= $char) && ($char <= ord('Z'))) ||
  1061. ((ord('a') <= $char) && ($char <= ord('z')))) {
  1062. $s .= chr($char);
  1063. ++$len;
  1064. } else {
  1065. $s .= '='.sprintf("%2X",$char);
  1066. $len += 3;
  1067. }
  1068. }
  1069. return $s;
  1070. }
  1071. function _sub_quoted_printable_encode($str, $encoding, $maxline, $linefeed)
  1072. {
  1073. global $_mb_encoding, $euc_match, $utf8_match, $sjis_match;
  1074. switch ($_mb_encoding[$encoding]) {
  1075. case 0 : //ascii
  1076. $allchars[0] = unpack("c*", $str);
  1077. $max = count($allchars[0]);
  1078. break;
  1079. case 1 : //euc-jp
  1080. $max = preg_match_all("/$euc_match/", $str, $allchars);
  1081. break;
  1082. case 2 : //shift-jis
  1083. $max = preg_match_all("/$sjis_match/", $str, $allchars);
  1084. break;
  1085. case 4 : //utf-8
  1086. $max = preg_match_all("/$utf8_match/", $str, $allchars);
  1087. break;
  1088. case 3 : //jis
  1089. $jis_match = "(?:^|\x1b\(B)([^\x1b]*)|\x1b$B([^\x1b]*)|\x1b\(I([^\x1b]*)";
  1090. $max = preg_match_all("/$jis_match/", $str, $allchunks, PREG_SET_ORDER); // 文字種ごとの配列に分解
  1091. $st = ''; // quoted printable変換後の文字列
  1092. $len = $maxline; // その行に追加可能なバイト数
  1093. $needterminate = FALSE; //最後にエスケープシーケンスが必要かどうか
  1094. for ($i = 0; $i < $max; ++$i) {
  1095. if (ord($allchunks[$i][1])) { //英数にマッチ
  1096. if ($needterminate) {
  1097. $st .= '=1B=28B';
  1098. $len -= 7;
  1099. }
  1100. $tmparr = unpack("C*", $allchunks[$i][1]);
  1101. foreach ($tmparr as $char) {
  1102. $tmp = _sub_qponechar(chr($char), $l);
  1103. if ($len < $l) {
  1104. $st .= $linefeed;
  1105. $len = $maxline;
  1106. }
  1107. $st .= $tmp;
  1108. $len -= $l;
  1109. }
  1110. $needterminate = FALSE;
  1111. } elseif (ord($allchunks[$i][2])) { //漢字にマッチ
  1112. $maxchars = preg_match_all("/../",substr($allchunks[$i][0], 3),$allchars);
  1113. $tmp = _sub_qponechar($allchars[0][0], $l);
  1114. if ($len < 14 + $l) {
  1115. if ($needterminate)
  1116. $st .= '=1B=28B';
  1117. $st .= $linefeed;
  1118. $len = $maxline;
  1119. }
  1120. $st .= '=1B=24B';
  1121. $len -= 7;
  1122. for ($j = 0; $j < $maxchars; ++$j) {
  1123. $tmp = _sub_qponechar($allchars[0][$j], $l);
  1124. if ($len < $l + 7) {
  1125. $st .= '=1B=28B'.$linefeed.'=1B=24B';
  1126. $len = $maxline-7;
  1127. }
  1128. $st .= $tmp;
  1129. $len -= $l;
  1130. }
  1131. $needterminate = TRUE;
  1132. } elseif (ord($allchunks[$i][3])) { //半角カナにマッチ
  1133. $max = preg_match_all("/./",$allchunks[$i][3],$allchars);
  1134. $tmp = _sub_qponechar($allchars[0][0], $l);
  1135. if ($len < 14 + $l) {
  1136. if ($needterminate)
  1137. $st .= '=1B=28B';
  1138. $st .= $linefeed;
  1139. $len = $maxline;
  1140. }
  1141. $st .= '=1B=28I';
  1142. $len -= 7;
  1143. for ($j == 0; $j < $max; ++$j) {
  1144. $tmp = _sub_qponechar($allchars[0][$j], $l);
  1145. if ($len < $l + 7) {
  1146. $st .= '=1B=28B'.$linefeed.'=1B=28I';
  1147. $len = $maxline-7;
  1148. }
  1149. $st .= $tmp;
  1150. $len -= $l;
  1151. }
  1152. $needterminate = TRUE;
  1153. }
  1154. }
  1155. if ($needterminate) $st .= '=1B=28B';
  1156. $st .= $linefeed;
  1157. return $st;
  1158. }
  1159. $st = ''; // quoted printable変換後の文字列
  1160. $len = $maxline; // その行に追加可能なバイト数
  1161. for ($i = 0; $i < $max; ++$i) {
  1162. $tmp = _sub_qponechar($allchars[0][$i], $l);
  1163. if ($l > $len) {
  1164. $st .= $linefeed;
  1165. $len = $maxline;
  1166. }
  1167. $st .= $tmp;
  1168. $len -= $l;
  1169. }
  1170. $st .= $linefeed;
  1171. return $st;
  1172. }
  1173. function _sub_encode_base64($str, $encoding, $maxline , $linefeed)
  1174. {
  1175. global $_mb_encoding, $euc_match, $utf8_match, $sjis_match;
  1176. switch ($_mb_encoding[$encoding]) {
  1177. case 0 : //ascii
  1178. return chunk_split( base64_encode($str) , $maxline, $linefeed);
  1179. case 1 : //euc-jp
  1180. $max = preg_match_all("/$euc_match/", $str, $allchars);
  1181. break;
  1182. case 2 : //shift-jis
  1183. $max = preg_match_all("/$sjis_match/", $str, $allchars);
  1184. break;
  1185. case 4 : //utf-8
  1186. $max = preg_match_all("/$utf8_match/", $str, $allchars);
  1187. break;
  1188. case 3 : //jis
  1189. $jis_match = "(?:^|\x1b\(B)([^\x1b]*)|\x1b$B([^\x1b]*)|\x1b\(I([^\x1b]*)";
  1190. $max = preg_match_all("/$jis_match/", $str, $allchunks, PREG_SET_ORDER); // 文字種ごとの配列に分解
  1191. $st = ''; // BASE64変換後の文字列
  1192. $maxbytes = floor($maxline * 3 / 4); //1行に変換可能なバイト数
  1193. $len = $maxbytes; // その行に追加可能なバイト数
  1194. $line = ''; //1行分の変換前の文字列
  1195. $needterminate = FALSE; //最後にエスケープシーケンスが必要かどうか
  1196. for ($i = 0; $i < $max; ++$i) {
  1197. if (ord($allchunks[$i][1])) { //英数にマッチ
  1198. if ($needterminate) {
  1199. $line .= chr(0x1B).'(B';
  1200. $len -= 3;
  1201. }
  1202. $tmpstr = $allchunks[$i][1]; //追加する文字列
  1203. $l = strlen($tmpstr); //追加する文字列の長さ
  1204. while ($l > $len) {
  1205. $line .= substr($tmpstr, 0, $len);
  1206. $st .= base64_encode($line).$linefeed;
  1207. $l -= $len;
  1208. $tmpstr = substr($tmpstr, $len);
  1209. $len = $maxbytes;
  1210. $line = '';
  1211. }
  1212. $line .= $tmpstr;
  1213. $len -= $l;
  1214. $needterminate = FALSE;
  1215. } elseif (ord($allchunks[$i][2])) { //漢字にマッチ
  1216. $tmpstr = substr($allchunks[$i][0], 3);
  1217. if ($len < 8) { //文字を追加するのに最低8バイト必要なので
  1218. if ($needterminate)
  1219. $line .= chr(0x1B).'(B';
  1220. $st .= base64_encode($line).$linefeed;
  1221. $len = $maxbytes;
  1222. $line = '';
  1223. }
  1224. $l = strlen($tmpstr);
  1225. $line .= chr(0x1B).'$B';
  1226. $len -= 3;
  1227. while ($l > $len-3) {
  1228. $add = floor(($len-3) / 2) * 2;
  1229. if ($add == 0) break;
  1230. $line .= substr($tmpstr, 0, $add).chr(0x1B).'(B';
  1231. $st .= base64_encode($line).$linefeed;
  1232. $l -= $add;
  1233. $tmpstr = substr($tmpstr, $add);
  1234. $len = $maxbytes-3;
  1235. $line = chr(0x1B).'$B';
  1236. }
  1237. $line .= $tmpstr;
  1238. $len -= $l;
  1239. $needterminate = TRUE;
  1240. } elseif (ord($allchunks[$i][3])) { //半角カナにマッチ
  1241. $tmpstr = $allchunks[$i][3];
  1242. if ($len < 7) { //文字を追加するのに最低7バイト必要なので
  1243. if ($needterminate)
  1244. $line .= chr(0x1B).'(B';
  1245. $st .= base64_encode($line).$linefeed;
  1246. $len = $maxbytes;
  1247. $line = '';
  1248. }
  1249. $l = strlen($tmpstr);
  1250. $line .= chr(0x1B).'(I';
  1251. $len -= 3;
  1252. while ($l > $len-3) {
  1253. $line .= substr($tmpstr, 0, $len-3).chr(0x1B).'(B';
  1254. $st .= base64_encode($line).$linefeed;
  1255. $l -= $len;
  1256. $tmpstr = substr($tmpstr, $len-3);
  1257. $len = $maxbytes-3;
  1258. $line = chr(0x1B).'(I';
  1259. }
  1260. $line .= $tmpstr;
  1261. $len -= $l;
  1262. $needterminate = TRUE;
  1263. }
  1264. }
  1265. if ($needterminate) $line .= chr(0x1B).'(B';
  1266. $st .= base64_encode($line).$linefeed;
  1267. return $st;
  1268. }
  1269. $st = ''; // BASE64変換後の文字列
  1270. $maxbytes = floor($maxline * 3 / 4); //1行に変換可能なバイト数
  1271. $len = $maxbytes; // その行に追加可能なバイト数
  1272. $line = ''; //1行分の変換前の文字列
  1273. for ($i = 0; $i < $max; ++$i) {
  1274. $l = strlen($allchars[0][$i]);
  1275. if ($l > $len) {
  1276. $st .= base64_encode($line).$linefeed;
  1277. $len = $maxbytes;
  1278. $line = '';
  1279. }
  1280. $line .= $allchars[0][$i];
  1281. $len -= $l;
  1282. }
  1283. $st .= base64_encode($line).$linefeed;
  1284. return $st;
  1285. }
  1286. function mb_encode_mimeheader( $str, $encoding = "ISO-2022-JP", $transfer_encoding = "B", $linefeed = "\r\n")
  1287. {
  1288. global $_mb_encoding;
  1289. if ($transfer_encoding == "b") $transfer_encoding = "B";
  1290. if ($transfer_encoding <> "B") $transfer_encoding = "Q";
  1291. $encoding = strtoupper($encoding);
  1292. $head = '=?' . mb_preferred_mime_name ($encoding) . '?'.$transfer_encoding.'?';
  1293. $str = mb_convert_encoding($str, $encoding, mb_internal_encoding());
  1294. $length = 76 - strlen($head) - 4;
  1295. if ($transfer_encoding == "B") {
  1296. $str = _sub_encode_base64( $str , $encoding, $length, $linefeed);
  1297. } else {
  1298. $str = _sub_quoted_printable_encode($str, $encoding, $length, $linefeed);
  1299. }
  1300. $ar = explode($linefeed, $str);
  1301. $s = '';
  1302. foreach ($ar as $element) {
  1303. if ($element <> '')
  1304. $s .= $head . $element . '?=' .$linefeed;
  1305. }
  1306. return $s;
  1307. }
  1308. ?>