PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/system/classes/utf8.php

https://bitbucket.org/alvinpd/monsterninja
PHP | 764 lines | 277 code | 92 blank | 395 comment | 34 complexity | c82f6d5de837f91ad9781806ce1f50fb MD5 | raw file
  1. <?php defined('SYSPATH') or die('No direct script access.');
  2. /**
  3. * A port of [phputf8](http://phputf8.sourceforge.net/) to a unified set
  4. * of files. Provides multi-byte aware replacement string functions.
  5. *
  6. * For UTF-8 support to work correctly, the following requirements must be met:
  7. *
  8. * - PCRE needs to be compiled with UTF-8 support (--enable-utf8)
  9. * - Support for [Unicode properties](http://php.net/manual/reference.pcre.pattern.modifiers.php)
  10. * is highly recommended (--enable-unicode-properties)
  11. * - UTF-8 conversion will be much more reliable if the
  12. * [iconv extension](http://php.net/iconv) is loaded
  13. * - The [mbstring extension](http://php.net/mbstring) is highly recommended,
  14. * but must not be overloading string functions
  15. *
  16. * [!!] This file is licensed differently from the rest of Kohana. As a port of
  17. * [phputf8](http://phputf8.sourceforge.net/), this file is released under the LGPL.
  18. *
  19. * @package Kohana
  20. * @category Base
  21. * @author Kohana Team
  22. * @copyright (c) 2007-2008 Kohana Team
  23. * @copyright (c) 2005 Harry Fuecks
  24. * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt
  25. */
  26. final class UTF8 {
  27. /**
  28. * @var boolean does the server support UTF-8 natively?
  29. */
  30. public static $server_utf8 = NULL;
  31. /**
  32. * @var array list of called methods
  33. */
  34. public static $called = array();
  35. /**
  36. * Recursively cleans arrays, objects, and strings. Removes ASCII control
  37. * codes and converts to the requested charset while silently discarding
  38. * incompatible characters.
  39. *
  40. * UTF8::clean($_GET); // Clean GET data
  41. *
  42. * [!!] This method requires [Iconv](http://php.net/iconv)
  43. *
  44. * @param mixed variable to clean
  45. * @param string character set, defaults to UTF-8
  46. * @return mixed
  47. * @uses UTF8::strip_ascci_ctrl
  48. * @uses UTF8::is_ascii
  49. */
  50. public static function clean($var, $charset = 'UTF-8')
  51. {
  52. if (is_array($var) OR is_object($var))
  53. {
  54. foreach ($var as $key => $val)
  55. {
  56. // Recursion!
  57. $var[self::clean($key)] = self::clean($val);
  58. }
  59. }
  60. elseif (is_string($var) AND $var !== '')
  61. {
  62. // Remove control characters
  63. $var = self::strip_ascii_ctrl($var);
  64. if ( ! self::is_ascii($var))
  65. {
  66. // Disable notices
  67. $ER = error_reporting(~E_NOTICE);
  68. // iconv is expensive, so it is only used when needed
  69. $var = iconv($charset, $charset.'//IGNORE', $var);
  70. // Turn notices back on
  71. error_reporting($ER);
  72. }
  73. }
  74. return $var;
  75. }
  76. /**
  77. * Tests whether a string contains only 7-bit ASCII bytes. This is used to
  78. * determine when to use native functions or UTF-8 functions.
  79. *
  80. * $ascii = UTF8::is_ascii($str);
  81. *
  82. * @param string string to check
  83. * @return bool
  84. */
  85. public static function is_ascii($str)
  86. {
  87. return ! preg_match('/[^\x00-\x7F]/S', $str);
  88. }
  89. /**
  90. * Strips out device control codes in the ASCII range.
  91. *
  92. * $str = UTF8::strip_ascii_ctrl($str);
  93. *
  94. * @param string string to clean
  95. * @return string
  96. */
  97. public static function strip_ascii_ctrl($str)
  98. {
  99. return preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $str);
  100. }
  101. /**
  102. * Strips out all non-7bit ASCII bytes.
  103. *
  104. * $str = UTF8::strip_non_ascii($str);
  105. *
  106. * @param string string to clean
  107. * @return string
  108. */
  109. public static function strip_non_ascii($str)
  110. {
  111. return preg_replace('/[^\x00-\x7F]+/S', '', $str);
  112. }
  113. /**
  114. * Replaces special/accented UTF-8 characters by ASCII-7 "equivalents".
  115. *
  116. * $ascii = UTF8::transliterate_to_ascii($utf8);
  117. *
  118. * @author Andreas Gohr <andi@splitbrain.org>
  119. * @param string string to transliterate
  120. * @param integer -1 lowercase only, +1 uppercase only, 0 both cases
  121. * @return string
  122. */
  123. public static function transliterate_to_ascii($str, $case = 0)
  124. {
  125. if ( ! isset(self::$called[__FUNCTION__]))
  126. {
  127. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  128. // Function has been called
  129. self::$called[__FUNCTION__] = TRUE;
  130. }
  131. return _transliterate_to_ascii($str, $case);
  132. }
  133. /**
  134. * Returns the length of the given string. This is a UTF8-aware version
  135. * of [strlen](http://php.net/strlen).
  136. *
  137. * $length = UTF8::strlen($str);
  138. *
  139. * @param string string being measured for length
  140. * @return integer
  141. * @uses UTF8::$server_utf8
  142. */
  143. public static function strlen($str)
  144. {
  145. if (UTF8::$server_utf8)
  146. return mb_strlen($str, Kohana::$charset);
  147. if ( ! isset(self::$called[__FUNCTION__]))
  148. {
  149. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  150. // Function has been called
  151. self::$called[__FUNCTION__] = TRUE;
  152. }
  153. return _strlen($str);
  154. }
  155. /**
  156. * Finds position of first occurrence of a UTF-8 string. This is a
  157. * UTF8-aware version of [strpos](http://php.net/strpos).
  158. *
  159. * $position = UTF8::strpos($str, $search);
  160. *
  161. * @author Harry Fuecks <hfuecks@gmail.com>
  162. * @param string haystack
  163. * @param string needle
  164. * @param integer offset from which character in haystack to start searching
  165. * @return integer position of needle
  166. * @return boolean FALSE if the needle is not found
  167. * @uses UTF8::$server_utf8
  168. */
  169. public static function strpos($str, $search, $offset = 0)
  170. {
  171. if (UTF8::$server_utf8)
  172. return mb_strpos($str, $search, $offset, Kohana::$charset);
  173. if ( ! isset(self::$called[__FUNCTION__]))
  174. {
  175. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  176. // Function has been called
  177. self::$called[__FUNCTION__] = TRUE;
  178. }
  179. return _strpos($str, $search, $offset);
  180. }
  181. /**
  182. * Finds position of last occurrence of a char in a UTF-8 string. This is
  183. * a UTF8-aware version of [strrpos](http://php.net/strrpos).
  184. *
  185. * $position = UTF8::strrpos($str, $search);
  186. *
  187. * @author Harry Fuecks <hfuecks@gmail.com>
  188. * @param string haystack
  189. * @param string needle
  190. * @param integer offset from which character in haystack to start searching
  191. * @return integer position of needle
  192. * @return boolean FALSE if the needle is not found
  193. * @uses UTF8::$server_utf8
  194. */
  195. public static function strrpos($str, $search, $offset = 0)
  196. {
  197. if (UTF8::$server_utf8)
  198. return mb_strrpos($str, $search, $offset, Kohana::$charset);
  199. if ( ! isset(self::$called[__FUNCTION__]))
  200. {
  201. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  202. // Function has been called
  203. self::$called[__FUNCTION__] = TRUE;
  204. }
  205. return _strrpos($str, $search, $offset);
  206. }
  207. /**
  208. * Returns part of a UTF-8 string. This is a UTF8-aware version
  209. * of [substr](http://php.net/substr).
  210. *
  211. * $sub = UTF8::substr($str, $offset);
  212. *
  213. * @author Chris Smith <chris@jalakai.co.uk>
  214. * @param string input string
  215. * @param integer offset
  216. * @param integer length limit
  217. * @return string
  218. * @uses UTF8::$server_utf8
  219. * @uses Kohana::$charset
  220. */
  221. public static function substr($str, $offset, $length = NULL)
  222. {
  223. if (UTF8::$server_utf8)
  224. return ($length === NULL)
  225. ? mb_substr($str, $offset, mb_strlen($str), Kohana::$charset)
  226. : mb_substr($str, $offset, $length, Kohana::$charset);
  227. if ( ! isset(self::$called[__FUNCTION__]))
  228. {
  229. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  230. // Function has been called
  231. self::$called[__FUNCTION__] = TRUE;
  232. }
  233. return _substr($str, $offset, $length);
  234. }
  235. /**
  236. * Replaces text within a portion of a UTF-8 string. This is a UTF8-aware
  237. * version of [substr_replace](http://php.net/substr_replace).
  238. *
  239. * $str = UTF8::substr_replace($str, $replacement, $offset);
  240. *
  241. * @author Harry Fuecks <hfuecks@gmail.com>
  242. * @param string input string
  243. * @param string replacement string
  244. * @param integer offset
  245. * @return string
  246. */
  247. public static function substr_replace($str, $replacement, $offset, $length = NULL)
  248. {
  249. if ( ! isset(self::$called[__FUNCTION__]))
  250. {
  251. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  252. // Function has been called
  253. self::$called[__FUNCTION__] = TRUE;
  254. }
  255. return _substr_replace($str, $replacement, $offset, $length);
  256. }
  257. /**
  258. * Makes a UTF-8 string lowercase. This is a UTF8-aware version
  259. * of [strtolower](http://php.net/strtolower).
  260. *
  261. * $str = UTF8::strtolower($str);
  262. *
  263. * @author Andreas Gohr <andi@splitbrain.org>
  264. * @param string mixed case string
  265. * @return string
  266. * @uses UTF8::$server_utf8
  267. */
  268. public static function strtolower($str)
  269. {
  270. if (UTF8::$server_utf8)
  271. return mb_strtolower($str, Kohana::$charset);
  272. if ( ! isset(self::$called[__FUNCTION__]))
  273. {
  274. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  275. // Function has been called
  276. self::$called[__FUNCTION__] = TRUE;
  277. }
  278. return _strtolower($str);
  279. }
  280. /**
  281. * Makes a UTF-8 string uppercase. This is a UTF8-aware version
  282. * of [strtoupper](http://php.net/strtoupper).
  283. *
  284. * @author Andreas Gohr <andi@splitbrain.org>
  285. * @param string mixed case string
  286. * @return string
  287. * @uses UTF8::$server_utf8
  288. * @uses Kohana::$charset
  289. */
  290. public static function strtoupper($str)
  291. {
  292. if (UTF8::$server_utf8)
  293. return mb_strtoupper($str, Kohana::$charset);
  294. if ( ! isset(self::$called[__FUNCTION__]))
  295. {
  296. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  297. // Function has been called
  298. self::$called[__FUNCTION__] = TRUE;
  299. }
  300. return _strtoupper($str);
  301. }
  302. /**
  303. * Makes a UTF-8 string's first character uppercase. This is a UTF8-aware
  304. * version of [ucfirst](http://php.net/ucfirst).
  305. *
  306. * $str = UTF8::ucfirst($str);
  307. *
  308. * @author Harry Fuecks <hfuecks@gmail.com>
  309. * @param string mixed case string
  310. * @return string
  311. */
  312. public static function ucfirst($str)
  313. {
  314. if ( ! isset(self::$called[__FUNCTION__]))
  315. {
  316. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  317. // Function has been called
  318. self::$called[__FUNCTION__] = TRUE;
  319. }
  320. return _ucfirst($str);
  321. }
  322. /**
  323. * Makes the first character of every word in a UTF-8 string uppercase.
  324. * This is a UTF8-aware version of [ucwords](http://php.net/ucwords).
  325. *
  326. * $str = UTF8::ucwords($str);
  327. *
  328. * @author Harry Fuecks <hfuecks@gmail.com>
  329. * @param string mixed case string
  330. * @return string
  331. * @uses UTF8::$server_utf8
  332. */
  333. public static function ucwords($str)
  334. {
  335. if (UTF8::$server_utf8)
  336. return mb_convert_case($str, MB_CASE_TITLE, Kohana::$charset);
  337. if ( ! isset(self::$called[__FUNCTION__]))
  338. {
  339. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  340. // Function has been called
  341. self::$called[__FUNCTION__] = TRUE;
  342. }
  343. return _ucwords($str);
  344. }
  345. /**
  346. * Case-insensitive UTF-8 string comparison. This is a UTF8-aware version
  347. * of [strcasecmp](http://php.net/strcasecmp).
  348. *
  349. * $compare = UTF8::strcasecmp($str1, $str2);
  350. *
  351. * @author Harry Fuecks <hfuecks@gmail.com>
  352. * @param string string to compare
  353. * @param string string to compare
  354. * @return integer less than 0 if str1 is less than str2
  355. * @return integer greater than 0 if str1 is greater than str2
  356. * @return integer 0 if they are equal
  357. */
  358. public static function strcasecmp($str1, $str2)
  359. {
  360. if ( ! isset(self::$called[__FUNCTION__]))
  361. {
  362. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  363. // Function has been called
  364. self::$called[__FUNCTION__] = TRUE;
  365. }
  366. return _strcasecmp($str1, $str2);
  367. }
  368. /**
  369. * Returns a string or an array with all occurrences of search in subject
  370. * (ignoring case) and replaced with the given replace value. This is a
  371. * UTF8-aware version of [str_ireplace](http://php.net/str_ireplace).
  372. *
  373. * [!!] This function is very slow compared to the native version. Avoid
  374. * using it when possible.
  375. *
  376. * @author Harry Fuecks <hfuecks@gmail.com
  377. * @param string|array text to replace
  378. * @param string|array replacement text
  379. * @param string|array subject text
  380. * @param integer number of matched and replaced needles will be returned via this parameter which is passed by reference
  381. * @return string if the input was a string
  382. * @return array if the input was an array
  383. */
  384. public static function str_ireplace($search, $replace, $str, & $count = NULL)
  385. {
  386. if ( ! isset(self::$called[__FUNCTION__]))
  387. {
  388. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  389. // Function has been called
  390. self::$called[__FUNCTION__] = TRUE;
  391. }
  392. return _str_ireplace($search, $replace, $str, $count);
  393. }
  394. /**
  395. * Case-insenstive UTF-8 version of strstr. Returns all of input string
  396. * from the first occurrence of needle to the end. This is a UTF8-aware
  397. * version of [stristr](http://php.net/stristr).
  398. *
  399. * $found = UTF8::stristr($str, $search);
  400. *
  401. * @author Harry Fuecks <hfuecks@gmail.com>
  402. * @param string input string
  403. * @param string needle
  404. * @return string matched substring if found
  405. * @return FALSE if the substring was not found
  406. */
  407. public static function stristr($str, $search)
  408. {
  409. if ( ! isset(self::$called[__FUNCTION__]))
  410. {
  411. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  412. // Function has been called
  413. self::$called[__FUNCTION__] = TRUE;
  414. }
  415. return _stristr($str, $search);
  416. }
  417. /**
  418. * Finds the length of the initial segment matching mask. This is a
  419. * UTF8-aware version of [strspn](http://php.net/strspn).
  420. *
  421. * $found = UTF8::strspn($str, $mask);
  422. *
  423. * @author Harry Fuecks <hfuecks@gmail.com>
  424. * @param string input string
  425. * @param string mask for search
  426. * @param integer start position of the string to examine
  427. * @param integer length of the string to examine
  428. * @return integer length of the initial segment that contains characters in the mask
  429. */
  430. public static function strspn($str, $mask, $offset = NULL, $length = NULL)
  431. {
  432. if ( ! isset(self::$called[__FUNCTION__]))
  433. {
  434. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  435. // Function has been called
  436. self::$called[__FUNCTION__] = TRUE;
  437. }
  438. return _strspn($str, $mask, $offset, $length);
  439. }
  440. /**
  441. * Finds the length of the initial segment not matching mask. This is a
  442. * UTF8-aware version of [strcspn](http://php.net/strcspn).
  443. *
  444. * $found = UTF8::strcspn($str, $mask);
  445. *
  446. * @author Harry Fuecks <hfuecks@gmail.com>
  447. * @param string input string
  448. * @param string mask for search
  449. * @param integer start position of the string to examine
  450. * @param integer length of the string to examine
  451. * @return integer length of the initial segment that contains characters not in the mask
  452. */
  453. public static function strcspn($str, $mask, $offset = NULL, $length = NULL)
  454. {
  455. if ( ! isset(self::$called[__FUNCTION__]))
  456. {
  457. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  458. // Function has been called
  459. self::$called[__FUNCTION__] = TRUE;
  460. }
  461. return _strcspn($str, $mask, $offset, $length);
  462. }
  463. /**
  464. * Pads a UTF-8 string to a certain length with another string. This is a
  465. * UTF8-aware version of [str_pad](http://php.net/str_pad).
  466. *
  467. * $str = UTF8::str_pad($str, $length);
  468. *
  469. * @author Harry Fuecks <hfuecks@gmail.com>
  470. * @param string input string
  471. * @param integer desired string length after padding
  472. * @param string string to use as padding
  473. * @param string padding type: STR_PAD_RIGHT, STR_PAD_LEFT, or STR_PAD_BOTH
  474. * @return string
  475. */
  476. public static function str_pad($str, $final_str_length, $pad_str = ' ', $pad_type = STR_PAD_RIGHT)
  477. {
  478. if ( ! isset(self::$called[__FUNCTION__]))
  479. {
  480. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  481. // Function has been called
  482. self::$called[__FUNCTION__] = TRUE;
  483. }
  484. return _str_pad($str, $final_str_length, $pad_str, $pad_type);
  485. }
  486. /**
  487. * Converts a UTF-8 string to an array. This is a UTF8-aware version of
  488. * [str_split](http://php.net/str_split).
  489. *
  490. * $array = UTF8::str_split($str);
  491. *
  492. * @author Harry Fuecks <hfuecks@gmail.com>
  493. * @param string input string
  494. * @param integer maximum length of each chunk
  495. * @return array
  496. */
  497. public static function str_split($str, $split_length = 1)
  498. {
  499. if ( ! isset(self::$called[__FUNCTION__]))
  500. {
  501. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  502. // Function has been called
  503. self::$called[__FUNCTION__] = TRUE;
  504. }
  505. return _str_split($str, $split_length);
  506. }
  507. /**
  508. * Reverses a UTF-8 string. This is a UTF8-aware version of [strrev](http://php.net/strrev).
  509. *
  510. * $str = UTF8::strrev($str);
  511. *
  512. * @author Harry Fuecks <hfuecks@gmail.com>
  513. * @param string string to be reversed
  514. * @return string
  515. */
  516. public static function strrev($str)
  517. {
  518. if ( ! isset(self::$called[__FUNCTION__]))
  519. {
  520. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  521. // Function has been called
  522. self::$called[__FUNCTION__] = TRUE;
  523. }
  524. return _strrev($str);
  525. }
  526. /**
  527. * Strips whitespace (or other UTF-8 characters) from the beginning and
  528. * end of a string. This is a UTF8-aware version of [trim](http://php.net/trim).
  529. *
  530. * $str = UTF8::trim($str);
  531. *
  532. * @author Andreas Gohr <andi@splitbrain.org>
  533. * @param string input string
  534. * @param string string of characters to remove
  535. * @return string
  536. */
  537. public static function trim($str, $charlist = NULL)
  538. {
  539. if ( ! isset(self::$called[__FUNCTION__]))
  540. {
  541. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  542. // Function has been called
  543. self::$called[__FUNCTION__] = TRUE;
  544. }
  545. return _trim($str, $charlist);
  546. }
  547. /**
  548. * Strips whitespace (or other UTF-8 characters) from the beginning of
  549. * a string. This is a UTF8-aware version of [ltrim](http://php.net/ltrim).
  550. *
  551. * $str = UTF8::ltrim($str);
  552. *
  553. * @author Andreas Gohr <andi@splitbrain.org>
  554. * @param string input string
  555. * @param string string of characters to remove
  556. * @return string
  557. */
  558. public static function ltrim($str, $charlist = NULL)
  559. {
  560. if ( ! isset(self::$called[__FUNCTION__]))
  561. {
  562. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  563. // Function has been called
  564. self::$called[__FUNCTION__] = TRUE;
  565. }
  566. return _ltrim($str, $charlist);
  567. }
  568. /**
  569. * Strips whitespace (or other UTF-8 characters) from the end of a string.
  570. * This is a UTF8-aware version of [rtrim](http://php.net/rtrim).
  571. *
  572. * $str = UTF8::rtrim($str);
  573. *
  574. * @author Andreas Gohr <andi@splitbrain.org>
  575. * @param string input string
  576. * @param string string of characters to remove
  577. * @return string
  578. */
  579. public static function rtrim($str, $charlist = NULL)
  580. {
  581. if ( ! isset(self::$called[__FUNCTION__]))
  582. {
  583. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  584. // Function has been called
  585. self::$called[__FUNCTION__] = TRUE;
  586. }
  587. return _rtrim($str, $charlist);
  588. }
  589. /**
  590. * Returns the unicode ordinal for a character. This is a UTF8-aware
  591. * version of [ord](http://php.net/ord).
  592. *
  593. * $digit = UTF8::ord($character);
  594. *
  595. * @author Harry Fuecks <hfuecks@gmail.com>
  596. * @param string UTF-8 encoded character
  597. * @return integer
  598. */
  599. public static function ord($chr)
  600. {
  601. if ( ! isset(self::$called[__FUNCTION__]))
  602. {
  603. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  604. // Function has been called
  605. self::$called[__FUNCTION__] = TRUE;
  606. }
  607. return _ord($chr);
  608. }
  609. /**
  610. * Takes an UTF-8 string and returns an array of ints representing the Unicode characters.
  611. * Astral planes are supported i.e. the ints in the output can be > 0xFFFF.
  612. * Occurrences of the BOM are ignored. Surrogates are not allowed.
  613. *
  614. * $array = UTF8::to_unicode($str);
  615. *
  616. * The Original Code is Mozilla Communicator client code.
  617. * The Initial Developer of the Original Code is Netscape Communications Corporation.
  618. * Portions created by the Initial Developer are Copyright (C) 1998 the Initial Developer.
  619. * Ported to PHP by Henri Sivonen <hsivonen@iki.fi>, see <http://hsivonen.iki.fi/php-utf8/>
  620. * Slight modifications to fit with phputf8 library by Harry Fuecks <hfuecks@gmail.com>
  621. *
  622. * @param string UTF-8 encoded string
  623. * @return array unicode code points
  624. * @return FALSE if the string is invalid
  625. */
  626. public static function to_unicode($str)
  627. {
  628. if ( ! isset(self::$called[__FUNCTION__]))
  629. {
  630. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  631. // Function has been called
  632. self::$called[__FUNCTION__] = TRUE;
  633. }
  634. return _to_unicode($str);
  635. }
  636. /**
  637. * Takes an array of ints representing the Unicode characters and returns a UTF-8 string.
  638. * Astral planes are supported i.e. the ints in the input can be > 0xFFFF.
  639. * Occurrances of the BOM are ignored. Surrogates are not allowed.
  640. *
  641. * $str = UTF8::to_unicode($array);
  642. *
  643. * The Original Code is Mozilla Communicator client code.
  644. * The Initial Developer of the Original Code is Netscape Communications Corporation.
  645. * Portions created by the Initial Developer are Copyright (C) 1998 the Initial Developer.
  646. * Ported to PHP by Henri Sivonen <hsivonen@iki.fi>, see http://hsivonen.iki.fi/php-utf8/
  647. * Slight modifications to fit with phputf8 library by Harry Fuecks <hfuecks@gmail.com>.
  648. *
  649. * @param array unicode code points representing a string
  650. * @return string utf8 string of characters
  651. * @return boolean FALSE if a code point cannot be found
  652. */
  653. public static function from_unicode($arr)
  654. {
  655. if ( ! isset(self::$called[__FUNCTION__]))
  656. {
  657. require SYSPATH.'utf8/'.__FUNCTION__.EXT;
  658. // Function has been called
  659. self::$called[__FUNCTION__] = TRUE;
  660. }
  661. return _from_unicode($arr);
  662. }
  663. private function __construct()
  664. {
  665. // This is a static class
  666. }
  667. } // End UTF8
  668. if (UTF8::$server_utf8 === NULL)
  669. {
  670. // Determine if this server supports UTF-8 natively
  671. UTF8::$server_utf8 = extension_loaded('mbstring');
  672. }