76        array(
'µ', 
'ſ', 
"\xCD\x85", 
'ς', 
"\xCF\x90", 
"\xCF\x91", 
"\xCF\x95", 
"\xCF\x96", 
"\xCF\xB0", 
"\xCF\xB1", 
"\xCF\xB5", 
"\xE1\xBA\x9B", 
"\xE1\xBE\xBE"),
 
   77        array(
'μ', 
's', 
'ι',        
'σ', 
'β',        
'θ',        
'φ',        
'π',        
'κ',        
'ρ',        
'ε',        
"\xE1\xB9\xA1", 
'ι'),
 
   82        if (\is_array($fromEncoding) || 
false !== strpos($fromEncoding, 
',')) {
 
   90        if (
'BASE64' === $fromEncoding) {
 
   91            $s = base64_decode(
$s);
 
   92            $fromEncoding = $toEncoding;
 
   95        if (
'BASE64' === $toEncoding) {
 
   96            return base64_encode(
$s);
 
   99        if (
'HTML-ENTITIES' === $toEncoding || 
'HTML' === $toEncoding) {
 
  100            if (
'HTML-ENTITIES' === $fromEncoding || 
'HTML' === $fromEncoding) {
 
  101                $fromEncoding = 
'Windows-1252';
 
  103            if (
'UTF-8' !== $fromEncoding) {
 
  104                $s = iconv($fromEncoding, 
'UTF-8//IGNORE', 
$s);
 
  107            return preg_replace_callback(
'/[\x80-\xFF]+/', array(__CLASS__, 
'html_encoding_callback'), 
$s);
 
  110        if (
'HTML-ENTITIES' === $fromEncoding) {
 
  111            $s = html_entity_decode(
$s, ENT_COMPAT, 
'UTF-8');
 
  112            $fromEncoding = 
'UTF-8';
 
  115        return iconv($fromEncoding, $toEncoding.
'//IGNORE', 
$s);
 
  118    public static function mb_convert_variables($toEncoding, $fromEncoding, &$a = 
null, &$b = 
null, &
$c = 
null, &
$d = 
null, &$e = 
null, &
$f = 
null)
 
  120        $vars = array(&$a, &$b, &
$c, &
$d, &$e, &
$f);
 
  123        array_walk_recursive($vars, 
function (&$v) use (&
$ok, $toEncoding, $fromEncoding) {
 
  129        return $ok ? $fromEncoding : 
false;
 
  134        return iconv_mime_decode(
$s, 2, self::$internalEncoding);
 
  137    public static function mb_encode_mimeheader(
$s, $charset = 
null, $transferEncoding = 
null, $linefeed = 
null, $indent = 
null)
 
  139        trigger_error(
'mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', E_USER_WARNING);
 
  144        if (
null !== 
$s && !\is_scalar(
$s) && !(\is_object(
$s) && \method_exists(
$s, 
'__toString'))) {
 
  145            trigger_error(
'mb_decode_numericentity() expects parameter 1 to be string, '.\gettype(
$s).
' given', E_USER_WARNING);
 
  150        if (!\is_array($convmap) || !$convmap) {
 
  154        if (
null !== $encoding && !\is_scalar($encoding)) {
 
  155            trigger_error(
'mb_decode_numericentity() expects parameter 3 to be string, '.\gettype(
$s).
' given', E_USER_WARNING);
 
  167        if (
'UTF-8' === $encoding) {
 
  169            if (!preg_match(
'//u', 
$s)) {
 
  170                $s = @iconv(
'UTF-8', 
'UTF-8//IGNORE', 
$s);
 
  173            $s = iconv($encoding, 
'UTF-8//IGNORE', 
$s);
 
  176        $cnt = floor(\count($convmap) / 4) * 4;
 
  178        for (
$i = 0; 
$i < $cnt; 
$i += 4) {
 
  180            $convmap[
$i] += $convmap[
$i + 2];
 
  181            $convmap[
$i + 1] += $convmap[
$i + 2];
 
  184        $s = preg_replace_callback(
'/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', 
function (array 
$m) use ($cnt, $convmap) {
 
  185            $c = isset(
$m[2]) ? (int) hexdec(
$m[2]) : 
$m[1];
 
  186            for (
$i = 0; 
$i < $cnt; 
$i += 4) {
 
  187                if (
$c >= $convmap[
$i] && 
$c <= $convmap[
$i + 1]) {
 
  195        if (
null === $encoding) {
 
  199        return iconv(
'UTF-8', $encoding.
'//IGNORE', 
$s);
 
  204        if (
null !== 
$s && !\is_scalar(
$s) && !(\is_object(
$s) && \method_exists(
$s, 
'__toString'))) {
 
  205            trigger_error(
'mb_encode_numericentity() expects parameter 1 to be string, '.\gettype(
$s).
' given', E_USER_WARNING);
 
  210        if (!\is_array($convmap) || !$convmap) {
 
  214        if (
null !== $encoding && !\is_scalar($encoding)) {
 
  215            trigger_error(
'mb_encode_numericentity() expects parameter 3 to be string, '.\gettype(
$s).
' given', E_USER_WARNING);
 
  220        if (
null !== $is_hex && !\is_scalar($is_hex)) {
 
  221            trigger_error(
'mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype(
$s).
' given', E_USER_WARNING);
 
  233        if (
'UTF-8' === $encoding) {
 
  235            if (!preg_match(
'//u', 
$s)) {
 
  236                $s = @iconv(
'UTF-8', 
'UTF-8//IGNORE', 
$s);
 
  239            $s = iconv($encoding, 
'UTF-8//IGNORE', 
$s);
 
  242        static $ulenMask = array(
"\xC0" => 2, 
"\xD0" => 2, 
"\xE0" => 3, 
"\xF0" => 4);
 
  244        $cnt = floor(\count($convmap) / 4) * 4;
 
  250            $ulen = 
$s[
$i] < 
"\x80" ? 1 : $ulenMask[
$s[
$i] & 
"\xF0"];
 
  251            $uchr = substr(
$s, 
$i, $ulen);
 
  255            for ($j = 0; $j < $cnt; $j += 4) {
 
  256                if (
$c >= $convmap[$j] && 
$c <= $convmap[$j + 1]) {
 
  257                    $cOffset = (
$c + $convmap[$j + 2]) & $convmap[$j + 3];
 
  258                    $result .= $is_hex ? sprintf(
'&#x%X;', $cOffset) : 
'&#'.$cOffset.
';';
 
  265        if (
null === $encoding) {
 
  269        return iconv(
'UTF-8', $encoding.
'//IGNORE', 
$result);
 
  281        if (
'UTF-8' === $encoding) {
 
  283            if (!preg_match(
'//u', 
$s)) {
 
  284                $s = @iconv(
'UTF-8', 
'UTF-8//IGNORE', 
$s);
 
  287            $s = iconv($encoding, 
'UTF-8//IGNORE', 
$s);
 
  290        if (MB_CASE_TITLE == $mode) {
 
  291            static $titleRegexp = 
null;
 
  292            if (
null === $titleRegexp) {
 
  295            $s = preg_replace_callback($titleRegexp, array(__CLASS__, 
'title_case'), 
$s);
 
  297            if (MB_CASE_UPPER == $mode) {
 
  298                static $upper = 
null;
 
  299                if (
null === $upper) {
 
  304                if (self::MB_CASE_FOLD === $mode) {
 
  305                    $s = str_replace(self::$caseFold[0], self::$caseFold[1], 
$s);
 
  308                static $lower = 
null;
 
  309                if (
null === $lower) {
 
  315            static $ulenMask = array(
"\xC0" => 2, 
"\xD0" => 2, 
"\xE0" => 3, 
"\xF0" => 4);
 
  321                $ulen = 
$s[
$i] < 
"\x80" ? 1 : $ulenMask[
$s[
$i] & 
"\xF0"];
 
  322                $uchr = substr(
$s, 
$i, $ulen);
 
  325                if (isset(
$map[$uchr])) {
 
  327                    $nlen = \strlen($uchr);
 
  329                    if ($nlen == $ulen) {
 
  332                            $s[--$nlen] = $uchr[--$ulen];
 
  335                        $s = substr_replace(
$s, $uchr, 
$i - $ulen, $ulen);
 
  336                        $len += $nlen - $ulen;
 
  343        if (
null === $encoding) {
 
  347        return iconv(
'UTF-8', $encoding.
'//IGNORE', 
$s);
 
  352        if (
null === $encoding) {
 
  358        if (
'UTF-8' === $encoding || 
false !== @iconv($encoding, $encoding, 
' ')) {
 
  359            self::$internalEncoding = $encoding;
 
  369        if (
null === 
$lang) {
 
  386        return array(
'UTF-8');
 
  391        switch (strtoupper($encoding)) {
 
  394                return array(
'utf8');
 
  402        if (
null === $encoding) {
 
  426                    if (!preg_match(
'/[\x80-\xFF]/', $str)) {
 
  433                    if (preg_match(
'//u', $str)) {
 
  439                    if (0 === strncmp($enc, 
'ISO-8859-', 9)) {
 
  462                    if (strncmp($enc, 
'ISO-8859-', 9)) {
 
  480        if (
'CP850' === $encoding || 
'ASCII' === $encoding) {
 
  484        return @iconv_strlen(
$s, $encoding);
 
  487    public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = 
null)
 
  490        if (
'CP850' === $encoding || 
'ASCII' === $encoding) {
 
  491            return strpos($haystack, $needle, $offset);
 
  494        $needle = (string) $needle;
 
  495        if (
'' === $needle) {
 
  496            trigger_error(__METHOD__.
': Empty delimiter', E_USER_WARNING);
 
  501        return iconv_strpos($haystack, $needle, $offset, $encoding);
 
  504    public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = 
null)
 
  507        if (
'CP850' === $encoding || 
'ASCII' === $encoding) {
 
  508            return strrpos($haystack, $needle, $offset);
 
  511        if ($offset != (
int) $offset) {
 
  513        } elseif ($offset = (
int) $offset) {
 
  518                $haystack = 
self::mb_substr($haystack, $offset, 2147483647, $encoding);
 
  522        $pos = iconv_strrpos($haystack, $needle, $encoding);
 
  524        return false !== $pos ? $offset + $pos : 
false;
 
  527    public static function mb_str_split($string, $split_length = 1, $encoding = 
null)
 
  529        if (
null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, 
'__toString'))) {
 
  530            trigger_error(
'mb_str_split() expects parameter 1 to be string, '.\gettype($string).
' given', E_USER_WARNING);
 
  535        if ($split_length < 1) {
 
  536            trigger_error(
'The length of each segment must be greater than zero', E_USER_WARNING);
 
  541        if (
null === $encoding) {
 
  548        for (
$i = 0; 
$i < $length; 
$i += $split_length) {
 
  567        if (0 === strcasecmp(
$c, 
'none')) {
 
  571        return null !== 
$c ? false : 
'none';
 
  577        if (
'CP850' === $encoding || 
'ASCII' === $encoding) {
 
  578            return (
string) substr(
$s, 
$start, 
null === $length ? 2147483647 : $length);
 
  588        if (
null === $length) {
 
  589            $length = 2147483647;
 
  590        } elseif ($length < 0) {
 
  591            $length = iconv_strlen(
$s, $encoding) + $length - 
$start;
 
  597        return (
string) iconv_substr(
$s, 
$start, $length, $encoding);
 
  600    public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = 
null)
 
  608    public static function mb_stristr($haystack, $needle, $part = 
false, $encoding = 
null)
 
  615    public static function mb_strrchr($haystack, $needle, $part = 
false, $encoding = 
null)
 
  618        if (
'CP850' === $encoding || 
'ASCII' === $encoding) {
 
  619            return strrchr($haystack, $needle, $part);
 
  622        $pos = iconv_strrpos($haystack, $needle, $encoding);
 
  627    public static function mb_strrichr($haystack, $needle, $part = 
false, $encoding = 
null)
 
  635    public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = 
null)
 
  643    public static function mb_strstr($haystack, $needle, $part = 
false, $encoding = 
null)
 
  645        $pos = strpos($haystack, $needle);
 
  646        if (
false === $pos) {
 
  650            return substr($haystack, 0, $pos);
 
  653        return substr($haystack, $pos);
 
  659            'internal_encoding' => self::$internalEncoding,
 
  660            'http_output' => 
'pass',
 
  661            'http_output_conv_mimetypes' => 
'^(text/|application/xhtml\+xml)',
 
  662            'func_overload' => 0,
 
  663            'func_overload_list' => 
'no overload',
 
  664            'mail_charset' => 
'UTF-8',
 
  665            'mail_header_encoding' => 
'BASE64',
 
  666            'mail_body_encoding' => 
'BASE64',
 
  667            'illegal_chars' => 0,
 
  668            'encoding_translation' => 
'Off',
 
  670            'detect_order' => self::$encodingList,
 
  671            'substitute_character' => 
'none',
 
  672            'strict_detection' => 
'Off',
 
  675        if (
'all' === 
$type) {
 
  692        return null !== $encoding ? 
'pass' === $encoding : 
'pass';
 
  699        if (
'UTF-8' !== $encoding) {
 
  700            $s = iconv($encoding, 
'UTF-8//IGNORE', 
$s);
 
  703        $s = preg_replace(
'/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', 
'', 
$s, -1, $wide);
 
  705        return ($wide << 1) + iconv_strlen(
$s, 
'UTF-8');
 
  710        return substr_count($haystack, $needle);
 
  720        if (0x80 > 
$code %= 0x200000) {
 
  722        } elseif (0x800 > 
$code) {
 
  724        } elseif (0x10000 > 
$code) {
 
  725            $s = \chr(0xE0 | 
$code >> 12).\chr(0x80 | 
$code >> 6 & 0x3F).\chr(0x80 | 
$code & 0x3F);
 
  727            $s = \chr(0xF0 | 
$code >> 18).\chr(0x80 | 
$code >> 12 & 0x3F).\chr(0x80 | 
$code >> 6 & 0x3F).\chr(0x80 | 
$code & 0x3F);
 
  730        if (
'UTF-8' !== $encoding = self::getEncoding($encoding)) {
 
  737    public static function mb_ord(
$s, $encoding = 
null)
 
  739        if (
'UTF-8' !== $encoding = self::getEncoding($encoding)) {
 
  743        if (1 === \strlen(
$s)) {
 
  747        $code = (
$s = unpack(
'C*', substr(
$s, 0, 4))) ? 
$s[1] : 0;
 
  749            return ((
$code - 0xF0) << 18) + ((
$s[2] - 0x80) << 12) + ((
$s[3] - 0x80) << 6) + 
$s[4] - 0x80;
 
  752            return ((
$code - 0xE0) << 12) + ((
$s[2] - 0x80) << 6) + 
$s[3] - 0x80;
 
  755            return ((
$code - 0xC0) << 6) + 
$s[2] - 0x80;
 
  761    private static function getSubpart($pos, $part, $haystack, $encoding)
 
  763        if (
false === $pos) {
 
  777        $m = unpack(
'C*', htmlentities(
$m[0], ENT_COMPAT, 
'UTF-8'));
 
  779        while (isset(
$m[
$i])) {
 
  781                $entities .= \chr(
$m[
$i++]);
 
  784            if (0xF0 <= 
$m[
$i]) {
 
  785                $c = ((
$m[
$i++] - 0xF0) << 18) + ((
$m[
$i++] - 0x80) << 12) + ((
$m[
$i++] - 0x80) << 6) + 
$m[
$i++] - 0x80;
 
  786            } elseif (0xE0 <= 
$m[
$i]) {
 
  787                $c = ((
$m[
$i++] - 0xE0) << 12) + ((
$m[
$i++] - 0x80) << 6) + 
$m[
$i++] - 0x80;
 
  789                $c = ((
$m[
$i++] - 0xC0) << 6) + 
$m[
$i++] - 0x80;
 
  792            $entities .= 
'&#'.$c.
';';
 
  805        if (file_exists($file = __DIR__.
'/Resources/unidata/'.$file.
'.php')) {
 
  806            return require $file;
 
  814        if (
null === $encoding) {
 
  818        $encoding = strtoupper($encoding);
 
  820        if (
'8BIT' === $encoding || 
'BINARY' === $encoding) {
 
  823        if (
'UTF8' === $encoding) {
 
An exception for terminatinating execution or to throw for unit testing.
Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
static mb_http_input($type='')
static html_encoding_callback(array $m)
static mb_encode_mimeheader($s, $charset=null, $transferEncoding=null, $linefeed=null, $indent=null)
static mb_decode_mimeheader($s)
static mb_internal_encoding($encoding=null)
static mb_stripos($haystack, $needle, $offset=0, $encoding=null)
static mb_strrchr($haystack, $needle, $part=false, $encoding=null)
static mb_decode_numericentity($s, $convmap, $encoding=null)
static mb_list_encodings()
static mb_strlen($s, $encoding=null)
static mb_http_output($encoding=null)
static mb_language($lang=null)
static mb_strripos($haystack, $needle, $offset=0, $encoding=null)
static mb_convert_encoding($s, $toEncoding, $fromEncoding=null)
static mb_strpos($haystack, $needle, $offset=0, $encoding=null)
static title_case(array $s)
static mb_substr($s, $start, $length=null, $encoding=null)
static mb_encode_numericentity($s, $convmap, $encoding=null, $is_hex=false)
static mb_str_split($string, $split_length=1, $encoding=null)
static mb_output_handler($contents, $status)
static mb_detect_encoding($str, $encodingList=null, $strict=false)
static mb_stristr($haystack, $needle, $part=false, $encoding=null)
static mb_convert_variables($toEncoding, $fromEncoding, &$a=null, &$b=null, &$c=null, &$d=null, &$e=null, &$f=null)
static mb_check_encoding($var=null, $encoding=null)
static getSubpart($pos, $part, $haystack, $encoding)
static mb_strrichr($haystack, $needle, $part=false, $encoding=null)
static mb_substitute_character($c=null)
static mb_chr($code, $encoding=null)
static mb_strtolower($s, $encoding=null)
static mb_strrpos($haystack, $needle, $offset=0, $encoding=null)
static mb_strstr($haystack, $needle, $part=false, $encoding=null)
static mb_strwidth($s, $encoding=null)
static mb_strtoupper($s, $encoding=null)
static getEncoding($encoding)
static mb_substr_count($haystack, $needle, $encoding=null)
static mb_ord($s, $encoding=null)
static mb_get_info($type='all')
static mb_detect_order($encodingList=null)
static mb_encoding_aliases($encoding)
static mb_convert_case($s, $mode, $encoding=null)
for( $i=6;$i< 13;$i++) for($i=1; $i< 13; $i++) $d
for($i=1; $i<=count($kw_cases_sel); $i+=1) $lang