104fd306cSNickeau<?php 204fd306cSNickeau 304fd306cSNickeau/* 404fd306cSNickeau * This file is part of the Symfony package. 504fd306cSNickeau * 604fd306cSNickeau * (c) Fabien Potencier <fabien@symfony.com> 704fd306cSNickeau * 804fd306cSNickeau * For the full copyright and license information, please view the LICENSE 904fd306cSNickeau * file that was distributed with this source code. 1004fd306cSNickeau */ 1104fd306cSNickeau 1204fd306cSNickeaunamespace Symfony\Polyfill\Mbstring; 1304fd306cSNickeau 1404fd306cSNickeau/** 1504fd306cSNickeau * Partial mbstring implementation in PHP, iconv based, UTF-8 centric. 1604fd306cSNickeau * 1704fd306cSNickeau * Implemented: 1804fd306cSNickeau * - mb_chr - Returns a specific character from its Unicode code point 1904fd306cSNickeau * - mb_convert_encoding - Convert character encoding 2004fd306cSNickeau * - mb_convert_variables - Convert character code in variable(s) 2104fd306cSNickeau * - mb_decode_mimeheader - Decode string in MIME header field 2204fd306cSNickeau * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED 2304fd306cSNickeau * - mb_decode_numericentity - Decode HTML numeric string reference to character 2404fd306cSNickeau * - mb_encode_numericentity - Encode character to HTML numeric string reference 2504fd306cSNickeau * - mb_convert_case - Perform case folding on a string 2604fd306cSNickeau * - mb_detect_encoding - Detect character encoding 2704fd306cSNickeau * - mb_get_info - Get internal settings of mbstring 2804fd306cSNickeau * - mb_http_input - Detect HTTP input character encoding 2904fd306cSNickeau * - mb_http_output - Set/Get HTTP output character encoding 3004fd306cSNickeau * - mb_internal_encoding - Set/Get internal character encoding 3104fd306cSNickeau * - mb_list_encodings - Returns an array of all supported encodings 3204fd306cSNickeau * - mb_ord - Returns the Unicode code point of a character 3304fd306cSNickeau * - mb_output_handler - Callback function converts character encoding in output buffer 3404fd306cSNickeau * - mb_scrub - Replaces ill-formed byte sequences with substitute characters 3504fd306cSNickeau * - mb_strlen - Get string length 3604fd306cSNickeau * - mb_strpos - Find position of first occurrence of string in a string 3704fd306cSNickeau * - mb_strrpos - Find position of last occurrence of a string in a string 3804fd306cSNickeau * - mb_str_split - Convert a string to an array 3904fd306cSNickeau * - mb_strtolower - Make a string lowercase 4004fd306cSNickeau * - mb_strtoupper - Make a string uppercase 4104fd306cSNickeau * - mb_substitute_character - Set/Get substitution character 4204fd306cSNickeau * - mb_substr - Get part of string 4304fd306cSNickeau * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive 4404fd306cSNickeau * - mb_stristr - Finds first occurrence of a string within another, case insensitive 4504fd306cSNickeau * - mb_strrchr - Finds the last occurrence of a character in a string within another 4604fd306cSNickeau * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive 4704fd306cSNickeau * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive 4804fd306cSNickeau * - mb_strstr - Finds first occurrence of a string within another 4904fd306cSNickeau * - mb_strwidth - Return width of string 5004fd306cSNickeau * - mb_substr_count - Count the number of substring occurrences 5104fd306cSNickeau * 5204fd306cSNickeau * Not implemented: 5304fd306cSNickeau * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) 5404fd306cSNickeau * - mb_ereg_* - Regular expression with multibyte support 5504fd306cSNickeau * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable 5604fd306cSNickeau * - mb_preferred_mime_name - Get MIME charset string 5704fd306cSNickeau * - mb_regex_encoding - Returns current encoding for multibyte regex as string 5804fd306cSNickeau * - mb_regex_set_options - Set/Get the default options for mbregex functions 5904fd306cSNickeau * - mb_send_mail - Send encoded mail 6004fd306cSNickeau * - mb_split - Split multibyte string using regular expression 6104fd306cSNickeau * - mb_strcut - Get part of string 6204fd306cSNickeau * - mb_strimwidth - Get truncated string with specified width 6304fd306cSNickeau * 6404fd306cSNickeau * @author Nicolas Grekas <p@tchwork.com> 6504fd306cSNickeau * 6604fd306cSNickeau * @internal 6704fd306cSNickeau */ 6804fd306cSNickeaufinal class Mbstring 6904fd306cSNickeau{ 7004fd306cSNickeau public const MB_CASE_FOLD = \PHP_INT_MAX; 7104fd306cSNickeau 72*83c68632SNico private const SIMPLE_CASE_FOLD = [ 7304fd306cSNickeau ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"], 7404fd306cSNickeau ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'], 7504fd306cSNickeau ]; 7604fd306cSNickeau 7704fd306cSNickeau private static $encodingList = ['ASCII', 'UTF-8']; 7804fd306cSNickeau private static $language = 'neutral'; 7904fd306cSNickeau private static $internalEncoding = 'UTF-8'; 8004fd306cSNickeau 8104fd306cSNickeau public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) 8204fd306cSNickeau { 83*83c68632SNico if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) { 8404fd306cSNickeau $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); 8504fd306cSNickeau } else { 8604fd306cSNickeau $fromEncoding = self::getEncoding($fromEncoding); 8704fd306cSNickeau } 8804fd306cSNickeau 8904fd306cSNickeau $toEncoding = self::getEncoding($toEncoding); 9004fd306cSNickeau 9104fd306cSNickeau if ('BASE64' === $fromEncoding) { 9204fd306cSNickeau $s = base64_decode($s); 9304fd306cSNickeau $fromEncoding = $toEncoding; 9404fd306cSNickeau } 9504fd306cSNickeau 9604fd306cSNickeau if ('BASE64' === $toEncoding) { 9704fd306cSNickeau return base64_encode($s); 9804fd306cSNickeau } 9904fd306cSNickeau 10004fd306cSNickeau if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) { 10104fd306cSNickeau if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) { 10204fd306cSNickeau $fromEncoding = 'Windows-1252'; 10304fd306cSNickeau } 10404fd306cSNickeau if ('UTF-8' !== $fromEncoding) { 105*83c68632SNico $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s); 10604fd306cSNickeau } 10704fd306cSNickeau 10804fd306cSNickeau return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s); 10904fd306cSNickeau } 11004fd306cSNickeau 11104fd306cSNickeau if ('HTML-ENTITIES' === $fromEncoding) { 11204fd306cSNickeau $s = html_entity_decode($s, \ENT_COMPAT, 'UTF-8'); 11304fd306cSNickeau $fromEncoding = 'UTF-8'; 11404fd306cSNickeau } 11504fd306cSNickeau 116*83c68632SNico return iconv($fromEncoding, $toEncoding.'//IGNORE', $s); 11704fd306cSNickeau } 11804fd306cSNickeau 11904fd306cSNickeau public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars) 12004fd306cSNickeau { 12104fd306cSNickeau $ok = true; 12204fd306cSNickeau array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) { 12304fd306cSNickeau if (false === $v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding)) { 12404fd306cSNickeau $ok = false; 12504fd306cSNickeau } 12604fd306cSNickeau }); 12704fd306cSNickeau 12804fd306cSNickeau return $ok ? $fromEncoding : false; 12904fd306cSNickeau } 13004fd306cSNickeau 13104fd306cSNickeau public static function mb_decode_mimeheader($s) 13204fd306cSNickeau { 133*83c68632SNico return iconv_mime_decode($s, 2, self::$internalEncoding); 13404fd306cSNickeau } 13504fd306cSNickeau 13604fd306cSNickeau public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null) 13704fd306cSNickeau { 13804fd306cSNickeau trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING); 13904fd306cSNickeau } 14004fd306cSNickeau 14104fd306cSNickeau public static function mb_decode_numericentity($s, $convmap, $encoding = null) 14204fd306cSNickeau { 143*83c68632SNico if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { 14404fd306cSNickeau trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING); 14504fd306cSNickeau 14604fd306cSNickeau return null; 14704fd306cSNickeau } 14804fd306cSNickeau 14904fd306cSNickeau if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) { 15004fd306cSNickeau return false; 15104fd306cSNickeau } 15204fd306cSNickeau 153*83c68632SNico if (null !== $encoding && !\is_scalar($encoding)) { 15404fd306cSNickeau trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING); 15504fd306cSNickeau 15604fd306cSNickeau return ''; // Instead of null (cf. mb_encode_numericentity). 15704fd306cSNickeau } 15804fd306cSNickeau 15904fd306cSNickeau $s = (string) $s; 16004fd306cSNickeau if ('' === $s) { 16104fd306cSNickeau return ''; 16204fd306cSNickeau } 16304fd306cSNickeau 16404fd306cSNickeau $encoding = self::getEncoding($encoding); 16504fd306cSNickeau 16604fd306cSNickeau if ('UTF-8' === $encoding) { 16704fd306cSNickeau $encoding = null; 16804fd306cSNickeau if (!preg_match('//u', $s)) { 169*83c68632SNico $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); 17004fd306cSNickeau } 17104fd306cSNickeau } else { 172*83c68632SNico $s = iconv($encoding, 'UTF-8//IGNORE', $s); 17304fd306cSNickeau } 17404fd306cSNickeau 17504fd306cSNickeau $cnt = floor(\count($convmap) / 4) * 4; 17604fd306cSNickeau 17704fd306cSNickeau for ($i = 0; $i < $cnt; $i += 4) { 17804fd306cSNickeau // collector_decode_htmlnumericentity ignores $convmap[$i + 3] 17904fd306cSNickeau $convmap[$i] += $convmap[$i + 2]; 18004fd306cSNickeau $convmap[$i + 1] += $convmap[$i + 2]; 18104fd306cSNickeau } 18204fd306cSNickeau 18304fd306cSNickeau $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) { 18404fd306cSNickeau $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1]; 18504fd306cSNickeau for ($i = 0; $i < $cnt; $i += 4) { 18604fd306cSNickeau if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) { 18704fd306cSNickeau return self::mb_chr($c - $convmap[$i + 2]); 18804fd306cSNickeau } 18904fd306cSNickeau } 19004fd306cSNickeau 19104fd306cSNickeau return $m[0]; 19204fd306cSNickeau }, $s); 19304fd306cSNickeau 19404fd306cSNickeau if (null === $encoding) { 19504fd306cSNickeau return $s; 19604fd306cSNickeau } 19704fd306cSNickeau 198*83c68632SNico return iconv('UTF-8', $encoding.'//IGNORE', $s); 19904fd306cSNickeau } 20004fd306cSNickeau 20104fd306cSNickeau public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false) 20204fd306cSNickeau { 203*83c68632SNico if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { 20404fd306cSNickeau trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING); 20504fd306cSNickeau 20604fd306cSNickeau return null; 20704fd306cSNickeau } 20804fd306cSNickeau 20904fd306cSNickeau if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) { 21004fd306cSNickeau return false; 21104fd306cSNickeau } 21204fd306cSNickeau 213*83c68632SNico if (null !== $encoding && !\is_scalar($encoding)) { 21404fd306cSNickeau trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING); 21504fd306cSNickeau 21604fd306cSNickeau return null; // Instead of '' (cf. mb_decode_numericentity). 21704fd306cSNickeau } 21804fd306cSNickeau 219*83c68632SNico if (null !== $is_hex && !\is_scalar($is_hex)) { 22004fd306cSNickeau trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', \E_USER_WARNING); 22104fd306cSNickeau 22204fd306cSNickeau return null; 22304fd306cSNickeau } 22404fd306cSNickeau 22504fd306cSNickeau $s = (string) $s; 22604fd306cSNickeau if ('' === $s) { 22704fd306cSNickeau return ''; 22804fd306cSNickeau } 22904fd306cSNickeau 23004fd306cSNickeau $encoding = self::getEncoding($encoding); 23104fd306cSNickeau 23204fd306cSNickeau if ('UTF-8' === $encoding) { 23304fd306cSNickeau $encoding = null; 23404fd306cSNickeau if (!preg_match('//u', $s)) { 235*83c68632SNico $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); 23604fd306cSNickeau } 23704fd306cSNickeau } else { 238*83c68632SNico $s = iconv($encoding, 'UTF-8//IGNORE', $s); 23904fd306cSNickeau } 24004fd306cSNickeau 24104fd306cSNickeau static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; 24204fd306cSNickeau 24304fd306cSNickeau $cnt = floor(\count($convmap) / 4) * 4; 24404fd306cSNickeau $i = 0; 24504fd306cSNickeau $len = \strlen($s); 24604fd306cSNickeau $result = ''; 24704fd306cSNickeau 24804fd306cSNickeau while ($i < $len) { 24904fd306cSNickeau $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"]; 25004fd306cSNickeau $uchr = substr($s, $i, $ulen); 25104fd306cSNickeau $i += $ulen; 25204fd306cSNickeau $c = self::mb_ord($uchr); 25304fd306cSNickeau 25404fd306cSNickeau for ($j = 0; $j < $cnt; $j += 4) { 25504fd306cSNickeau if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) { 25604fd306cSNickeau $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3]; 25704fd306cSNickeau $result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';'; 25804fd306cSNickeau continue 2; 25904fd306cSNickeau } 26004fd306cSNickeau } 26104fd306cSNickeau $result .= $uchr; 26204fd306cSNickeau } 26304fd306cSNickeau 26404fd306cSNickeau if (null === $encoding) { 26504fd306cSNickeau return $result; 26604fd306cSNickeau } 26704fd306cSNickeau 268*83c68632SNico return iconv('UTF-8', $encoding.'//IGNORE', $result); 26904fd306cSNickeau } 27004fd306cSNickeau 27104fd306cSNickeau public static function mb_convert_case($s, $mode, $encoding = null) 27204fd306cSNickeau { 27304fd306cSNickeau $s = (string) $s; 27404fd306cSNickeau if ('' === $s) { 27504fd306cSNickeau return ''; 27604fd306cSNickeau } 27704fd306cSNickeau 27804fd306cSNickeau $encoding = self::getEncoding($encoding); 27904fd306cSNickeau 28004fd306cSNickeau if ('UTF-8' === $encoding) { 28104fd306cSNickeau $encoding = null; 28204fd306cSNickeau if (!preg_match('//u', $s)) { 283*83c68632SNico $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); 28404fd306cSNickeau } 28504fd306cSNickeau } else { 286*83c68632SNico $s = iconv($encoding, 'UTF-8//IGNORE', $s); 28704fd306cSNickeau } 28804fd306cSNickeau 28904fd306cSNickeau if (\MB_CASE_TITLE == $mode) { 29004fd306cSNickeau static $titleRegexp = null; 29104fd306cSNickeau if (null === $titleRegexp) { 29204fd306cSNickeau $titleRegexp = self::getData('titleCaseRegexp'); 29304fd306cSNickeau } 29404fd306cSNickeau $s = preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s); 29504fd306cSNickeau } else { 29604fd306cSNickeau if (\MB_CASE_UPPER == $mode) { 29704fd306cSNickeau static $upper = null; 29804fd306cSNickeau if (null === $upper) { 29904fd306cSNickeau $upper = self::getData('upperCase'); 30004fd306cSNickeau } 30104fd306cSNickeau $map = $upper; 30204fd306cSNickeau } else { 30304fd306cSNickeau if (self::MB_CASE_FOLD === $mode) { 304*83c68632SNico static $caseFolding = null; 305*83c68632SNico if (null === $caseFolding) { 306*83c68632SNico $caseFolding = self::getData('caseFolding'); 307*83c68632SNico } 308*83c68632SNico $s = strtr($s, $caseFolding); 30904fd306cSNickeau } 31004fd306cSNickeau 31104fd306cSNickeau static $lower = null; 31204fd306cSNickeau if (null === $lower) { 31304fd306cSNickeau $lower = self::getData('lowerCase'); 31404fd306cSNickeau } 31504fd306cSNickeau $map = $lower; 31604fd306cSNickeau } 31704fd306cSNickeau 31804fd306cSNickeau static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; 31904fd306cSNickeau 32004fd306cSNickeau $i = 0; 32104fd306cSNickeau $len = \strlen($s); 32204fd306cSNickeau 32304fd306cSNickeau while ($i < $len) { 32404fd306cSNickeau $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"]; 32504fd306cSNickeau $uchr = substr($s, $i, $ulen); 32604fd306cSNickeau $i += $ulen; 32704fd306cSNickeau 32804fd306cSNickeau if (isset($map[$uchr])) { 32904fd306cSNickeau $uchr = $map[$uchr]; 33004fd306cSNickeau $nlen = \strlen($uchr); 33104fd306cSNickeau 33204fd306cSNickeau if ($nlen == $ulen) { 33304fd306cSNickeau $nlen = $i; 33404fd306cSNickeau do { 33504fd306cSNickeau $s[--$nlen] = $uchr[--$ulen]; 33604fd306cSNickeau } while ($ulen); 33704fd306cSNickeau } else { 33804fd306cSNickeau $s = substr_replace($s, $uchr, $i - $ulen, $ulen); 33904fd306cSNickeau $len += $nlen - $ulen; 34004fd306cSNickeau $i += $nlen - $ulen; 34104fd306cSNickeau } 34204fd306cSNickeau } 34304fd306cSNickeau } 34404fd306cSNickeau } 34504fd306cSNickeau 34604fd306cSNickeau if (null === $encoding) { 34704fd306cSNickeau return $s; 34804fd306cSNickeau } 34904fd306cSNickeau 350*83c68632SNico return iconv('UTF-8', $encoding.'//IGNORE', $s); 35104fd306cSNickeau } 35204fd306cSNickeau 35304fd306cSNickeau public static function mb_internal_encoding($encoding = null) 35404fd306cSNickeau { 35504fd306cSNickeau if (null === $encoding) { 35604fd306cSNickeau return self::$internalEncoding; 35704fd306cSNickeau } 35804fd306cSNickeau 35904fd306cSNickeau $normalizedEncoding = self::getEncoding($encoding); 36004fd306cSNickeau 361*83c68632SNico if ('UTF-8' === $normalizedEncoding || false !== @iconv($normalizedEncoding, $normalizedEncoding, ' ')) { 36204fd306cSNickeau self::$internalEncoding = $normalizedEncoding; 36304fd306cSNickeau 36404fd306cSNickeau return true; 36504fd306cSNickeau } 36604fd306cSNickeau 36704fd306cSNickeau if (80000 > \PHP_VERSION_ID) { 36804fd306cSNickeau return false; 36904fd306cSNickeau } 37004fd306cSNickeau 37104fd306cSNickeau throw new \ValueError(sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding)); 37204fd306cSNickeau } 37304fd306cSNickeau 37404fd306cSNickeau public static function mb_language($lang = null) 37504fd306cSNickeau { 37604fd306cSNickeau if (null === $lang) { 37704fd306cSNickeau return self::$language; 37804fd306cSNickeau } 37904fd306cSNickeau 38004fd306cSNickeau switch ($normalizedLang = strtolower($lang)) { 38104fd306cSNickeau case 'uni': 38204fd306cSNickeau case 'neutral': 38304fd306cSNickeau self::$language = $normalizedLang; 38404fd306cSNickeau 38504fd306cSNickeau return true; 38604fd306cSNickeau } 38704fd306cSNickeau 38804fd306cSNickeau if (80000 > \PHP_VERSION_ID) { 38904fd306cSNickeau return false; 39004fd306cSNickeau } 39104fd306cSNickeau 39204fd306cSNickeau throw new \ValueError(sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang)); 39304fd306cSNickeau } 39404fd306cSNickeau 39504fd306cSNickeau public static function mb_list_encodings() 39604fd306cSNickeau { 39704fd306cSNickeau return ['UTF-8']; 39804fd306cSNickeau } 39904fd306cSNickeau 40004fd306cSNickeau public static function mb_encoding_aliases($encoding) 40104fd306cSNickeau { 40204fd306cSNickeau switch (strtoupper($encoding)) { 40304fd306cSNickeau case 'UTF8': 40404fd306cSNickeau case 'UTF-8': 40504fd306cSNickeau return ['utf8']; 40604fd306cSNickeau } 40704fd306cSNickeau 40804fd306cSNickeau return false; 40904fd306cSNickeau } 41004fd306cSNickeau 41104fd306cSNickeau public static function mb_check_encoding($var = null, $encoding = null) 41204fd306cSNickeau { 413*83c68632SNico if (PHP_VERSION_ID < 70200 && \is_array($var)) { 414*83c68632SNico trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING); 415*83c68632SNico 416*83c68632SNico return null; 417*83c68632SNico } 418*83c68632SNico 41904fd306cSNickeau if (null === $encoding) { 42004fd306cSNickeau if (null === $var) { 42104fd306cSNickeau return false; 42204fd306cSNickeau } 42304fd306cSNickeau $encoding = self::$internalEncoding; 42404fd306cSNickeau } 42504fd306cSNickeau 426*83c68632SNico if (!\is_array($var)) { 427*83c68632SNico return self::mb_detect_encoding($var, [$encoding]) || false !== @iconv($encoding, $encoding, $var); 428*83c68632SNico } 429*83c68632SNico 430*83c68632SNico foreach ($var as $key => $value) { 431*83c68632SNico if (!self::mb_check_encoding($key, $encoding)) { 432*83c68632SNico return false; 433*83c68632SNico } 434*83c68632SNico if (!self::mb_check_encoding($value, $encoding)) { 435*83c68632SNico return false; 436*83c68632SNico } 437*83c68632SNico } 438*83c68632SNico 439*83c68632SNico return true; 440*83c68632SNico 44104fd306cSNickeau } 44204fd306cSNickeau 44304fd306cSNickeau public static function mb_detect_encoding($str, $encodingList = null, $strict = false) 44404fd306cSNickeau { 44504fd306cSNickeau if (null === $encodingList) { 44604fd306cSNickeau $encodingList = self::$encodingList; 44704fd306cSNickeau } else { 44804fd306cSNickeau if (!\is_array($encodingList)) { 44904fd306cSNickeau $encodingList = array_map('trim', explode(',', $encodingList)); 45004fd306cSNickeau } 45104fd306cSNickeau $encodingList = array_map('strtoupper', $encodingList); 45204fd306cSNickeau } 45304fd306cSNickeau 45404fd306cSNickeau foreach ($encodingList as $enc) { 45504fd306cSNickeau switch ($enc) { 45604fd306cSNickeau case 'ASCII': 45704fd306cSNickeau if (!preg_match('/[\x80-\xFF]/', $str)) { 45804fd306cSNickeau return $enc; 45904fd306cSNickeau } 46004fd306cSNickeau break; 46104fd306cSNickeau 46204fd306cSNickeau case 'UTF8': 46304fd306cSNickeau case 'UTF-8': 46404fd306cSNickeau if (preg_match('//u', $str)) { 46504fd306cSNickeau return 'UTF-8'; 46604fd306cSNickeau } 46704fd306cSNickeau break; 46804fd306cSNickeau 46904fd306cSNickeau default: 47004fd306cSNickeau if (0 === strncmp($enc, 'ISO-8859-', 9)) { 47104fd306cSNickeau return $enc; 47204fd306cSNickeau } 47304fd306cSNickeau } 47404fd306cSNickeau } 47504fd306cSNickeau 47604fd306cSNickeau return false; 47704fd306cSNickeau } 47804fd306cSNickeau 47904fd306cSNickeau public static function mb_detect_order($encodingList = null) 48004fd306cSNickeau { 48104fd306cSNickeau if (null === $encodingList) { 48204fd306cSNickeau return self::$encodingList; 48304fd306cSNickeau } 48404fd306cSNickeau 48504fd306cSNickeau if (!\is_array($encodingList)) { 48604fd306cSNickeau $encodingList = array_map('trim', explode(',', $encodingList)); 48704fd306cSNickeau } 48804fd306cSNickeau $encodingList = array_map('strtoupper', $encodingList); 48904fd306cSNickeau 49004fd306cSNickeau foreach ($encodingList as $enc) { 49104fd306cSNickeau switch ($enc) { 49204fd306cSNickeau default: 49304fd306cSNickeau if (strncmp($enc, 'ISO-8859-', 9)) { 49404fd306cSNickeau return false; 49504fd306cSNickeau } 49604fd306cSNickeau // no break 49704fd306cSNickeau case 'ASCII': 49804fd306cSNickeau case 'UTF8': 49904fd306cSNickeau case 'UTF-8': 50004fd306cSNickeau } 50104fd306cSNickeau } 50204fd306cSNickeau 50304fd306cSNickeau self::$encodingList = $encodingList; 50404fd306cSNickeau 50504fd306cSNickeau return true; 50604fd306cSNickeau } 50704fd306cSNickeau 50804fd306cSNickeau public static function mb_strlen($s, $encoding = null) 50904fd306cSNickeau { 51004fd306cSNickeau $encoding = self::getEncoding($encoding); 51104fd306cSNickeau if ('CP850' === $encoding || 'ASCII' === $encoding) { 51204fd306cSNickeau return \strlen($s); 51304fd306cSNickeau } 51404fd306cSNickeau 515*83c68632SNico return @iconv_strlen($s, $encoding); 51604fd306cSNickeau } 51704fd306cSNickeau 51804fd306cSNickeau public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) 51904fd306cSNickeau { 52004fd306cSNickeau $encoding = self::getEncoding($encoding); 52104fd306cSNickeau if ('CP850' === $encoding || 'ASCII' === $encoding) { 52204fd306cSNickeau return strpos($haystack, $needle, $offset); 52304fd306cSNickeau } 52404fd306cSNickeau 52504fd306cSNickeau $needle = (string) $needle; 52604fd306cSNickeau if ('' === $needle) { 52704fd306cSNickeau if (80000 > \PHP_VERSION_ID) { 52804fd306cSNickeau trigger_error(__METHOD__.': Empty delimiter', \E_USER_WARNING); 52904fd306cSNickeau 53004fd306cSNickeau return false; 53104fd306cSNickeau } 53204fd306cSNickeau 53304fd306cSNickeau return 0; 53404fd306cSNickeau } 53504fd306cSNickeau 536*83c68632SNico return iconv_strpos($haystack, $needle, $offset, $encoding); 53704fd306cSNickeau } 53804fd306cSNickeau 53904fd306cSNickeau public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) 54004fd306cSNickeau { 54104fd306cSNickeau $encoding = self::getEncoding($encoding); 54204fd306cSNickeau if ('CP850' === $encoding || 'ASCII' === $encoding) { 54304fd306cSNickeau return strrpos($haystack, $needle, $offset); 54404fd306cSNickeau } 54504fd306cSNickeau 54604fd306cSNickeau if ($offset != (int) $offset) { 54704fd306cSNickeau $offset = 0; 54804fd306cSNickeau } elseif ($offset = (int) $offset) { 54904fd306cSNickeau if ($offset < 0) { 55004fd306cSNickeau if (0 > $offset += self::mb_strlen($needle)) { 55104fd306cSNickeau $haystack = self::mb_substr($haystack, 0, $offset, $encoding); 55204fd306cSNickeau } 55304fd306cSNickeau $offset = 0; 55404fd306cSNickeau } else { 55504fd306cSNickeau $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding); 55604fd306cSNickeau } 55704fd306cSNickeau } 55804fd306cSNickeau 55904fd306cSNickeau $pos = '' !== $needle || 80000 > \PHP_VERSION_ID 560*83c68632SNico ? iconv_strrpos($haystack, $needle, $encoding) 56104fd306cSNickeau : self::mb_strlen($haystack, $encoding); 56204fd306cSNickeau 56304fd306cSNickeau return false !== $pos ? $offset + $pos : false; 56404fd306cSNickeau } 56504fd306cSNickeau 56604fd306cSNickeau public static function mb_str_split($string, $split_length = 1, $encoding = null) 56704fd306cSNickeau { 568*83c68632SNico if (null !== $string && !\is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) { 56904fd306cSNickeau trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', \E_USER_WARNING); 57004fd306cSNickeau 57104fd306cSNickeau return null; 57204fd306cSNickeau } 57304fd306cSNickeau 57404fd306cSNickeau if (1 > $split_length = (int) $split_length) { 57504fd306cSNickeau if (80000 > \PHP_VERSION_ID) { 57604fd306cSNickeau trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING); 577*83c68632SNico 57804fd306cSNickeau return false; 57904fd306cSNickeau } 58004fd306cSNickeau 58104fd306cSNickeau throw new \ValueError('Argument #2 ($length) must be greater than 0'); 58204fd306cSNickeau } 58304fd306cSNickeau 58404fd306cSNickeau if (null === $encoding) { 58504fd306cSNickeau $encoding = mb_internal_encoding(); 58604fd306cSNickeau } 58704fd306cSNickeau 58804fd306cSNickeau if ('UTF-8' === $encoding = self::getEncoding($encoding)) { 58904fd306cSNickeau $rx = '/('; 59004fd306cSNickeau while (65535 < $split_length) { 59104fd306cSNickeau $rx .= '.{65535}'; 59204fd306cSNickeau $split_length -= 65535; 59304fd306cSNickeau } 59404fd306cSNickeau $rx .= '.{'.$split_length.'})/us'; 59504fd306cSNickeau 596*83c68632SNico return preg_split($rx, $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY); 59704fd306cSNickeau } 59804fd306cSNickeau 59904fd306cSNickeau $result = []; 60004fd306cSNickeau $length = mb_strlen($string, $encoding); 60104fd306cSNickeau 60204fd306cSNickeau for ($i = 0; $i < $length; $i += $split_length) { 60304fd306cSNickeau $result[] = mb_substr($string, $i, $split_length, $encoding); 60404fd306cSNickeau } 60504fd306cSNickeau 60604fd306cSNickeau return $result; 60704fd306cSNickeau } 60804fd306cSNickeau 60904fd306cSNickeau public static function mb_strtolower($s, $encoding = null) 61004fd306cSNickeau { 61104fd306cSNickeau return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding); 61204fd306cSNickeau } 61304fd306cSNickeau 61404fd306cSNickeau public static function mb_strtoupper($s, $encoding = null) 61504fd306cSNickeau { 61604fd306cSNickeau return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding); 61704fd306cSNickeau } 61804fd306cSNickeau 61904fd306cSNickeau public static function mb_substitute_character($c = null) 62004fd306cSNickeau { 62104fd306cSNickeau if (null === $c) { 62204fd306cSNickeau return 'none'; 62304fd306cSNickeau } 62404fd306cSNickeau if (0 === strcasecmp($c, 'none')) { 62504fd306cSNickeau return true; 62604fd306cSNickeau } 62704fd306cSNickeau if (80000 > \PHP_VERSION_ID) { 62804fd306cSNickeau return false; 62904fd306cSNickeau } 63004fd306cSNickeau if (\is_int($c) || 'long' === $c || 'entity' === $c) { 63104fd306cSNickeau return false; 63204fd306cSNickeau } 63304fd306cSNickeau 63404fd306cSNickeau throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint'); 63504fd306cSNickeau } 63604fd306cSNickeau 63704fd306cSNickeau public static function mb_substr($s, $start, $length = null, $encoding = null) 63804fd306cSNickeau { 63904fd306cSNickeau $encoding = self::getEncoding($encoding); 64004fd306cSNickeau if ('CP850' === $encoding || 'ASCII' === $encoding) { 64104fd306cSNickeau return (string) substr($s, $start, null === $length ? 2147483647 : $length); 64204fd306cSNickeau } 64304fd306cSNickeau 64404fd306cSNickeau if ($start < 0) { 645*83c68632SNico $start = iconv_strlen($s, $encoding) + $start; 64604fd306cSNickeau if ($start < 0) { 64704fd306cSNickeau $start = 0; 64804fd306cSNickeau } 64904fd306cSNickeau } 65004fd306cSNickeau 65104fd306cSNickeau if (null === $length) { 65204fd306cSNickeau $length = 2147483647; 65304fd306cSNickeau } elseif ($length < 0) { 654*83c68632SNico $length = iconv_strlen($s, $encoding) + $length - $start; 65504fd306cSNickeau if ($length < 0) { 65604fd306cSNickeau return ''; 65704fd306cSNickeau } 65804fd306cSNickeau } 65904fd306cSNickeau 660*83c68632SNico return (string) iconv_substr($s, $start, $length, $encoding); 66104fd306cSNickeau } 66204fd306cSNickeau 66304fd306cSNickeau public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) 66404fd306cSNickeau { 665*83c68632SNico [$haystack, $needle] = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], [ 666*83c68632SNico self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding), 667*83c68632SNico self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding), 668*83c68632SNico ]); 66904fd306cSNickeau 67004fd306cSNickeau return self::mb_strpos($haystack, $needle, $offset, $encoding); 67104fd306cSNickeau } 67204fd306cSNickeau 67304fd306cSNickeau public static function mb_stristr($haystack, $needle, $part = false, $encoding = null) 67404fd306cSNickeau { 67504fd306cSNickeau $pos = self::mb_stripos($haystack, $needle, 0, $encoding); 67604fd306cSNickeau 67704fd306cSNickeau return self::getSubpart($pos, $part, $haystack, $encoding); 67804fd306cSNickeau } 67904fd306cSNickeau 68004fd306cSNickeau public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null) 68104fd306cSNickeau { 68204fd306cSNickeau $encoding = self::getEncoding($encoding); 68304fd306cSNickeau if ('CP850' === $encoding || 'ASCII' === $encoding) { 68404fd306cSNickeau $pos = strrpos($haystack, $needle); 68504fd306cSNickeau } else { 68604fd306cSNickeau $needle = self::mb_substr($needle, 0, 1, $encoding); 687*83c68632SNico $pos = iconv_strrpos($haystack, $needle, $encoding); 68804fd306cSNickeau } 68904fd306cSNickeau 69004fd306cSNickeau return self::getSubpart($pos, $part, $haystack, $encoding); 69104fd306cSNickeau } 69204fd306cSNickeau 69304fd306cSNickeau public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null) 69404fd306cSNickeau { 69504fd306cSNickeau $needle = self::mb_substr($needle, 0, 1, $encoding); 69604fd306cSNickeau $pos = self::mb_strripos($haystack, $needle, $encoding); 69704fd306cSNickeau 69804fd306cSNickeau return self::getSubpart($pos, $part, $haystack, $encoding); 69904fd306cSNickeau } 70004fd306cSNickeau 70104fd306cSNickeau public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) 70204fd306cSNickeau { 703*83c68632SNico $haystack = self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding); 704*83c68632SNico $needle = self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding); 705*83c68632SNico 706*83c68632SNico $haystack = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $haystack); 707*83c68632SNico $needle = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $needle); 70804fd306cSNickeau 70904fd306cSNickeau return self::mb_strrpos($haystack, $needle, $offset, $encoding); 71004fd306cSNickeau } 71104fd306cSNickeau 71204fd306cSNickeau public static function mb_strstr($haystack, $needle, $part = false, $encoding = null) 71304fd306cSNickeau { 71404fd306cSNickeau $pos = strpos($haystack, $needle); 71504fd306cSNickeau if (false === $pos) { 71604fd306cSNickeau return false; 71704fd306cSNickeau } 71804fd306cSNickeau if ($part) { 71904fd306cSNickeau return substr($haystack, 0, $pos); 72004fd306cSNickeau } 72104fd306cSNickeau 72204fd306cSNickeau return substr($haystack, $pos); 72304fd306cSNickeau } 72404fd306cSNickeau 72504fd306cSNickeau public static function mb_get_info($type = 'all') 72604fd306cSNickeau { 72704fd306cSNickeau $info = [ 72804fd306cSNickeau 'internal_encoding' => self::$internalEncoding, 72904fd306cSNickeau 'http_output' => 'pass', 73004fd306cSNickeau 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)', 73104fd306cSNickeau 'func_overload' => 0, 73204fd306cSNickeau 'func_overload_list' => 'no overload', 73304fd306cSNickeau 'mail_charset' => 'UTF-8', 73404fd306cSNickeau 'mail_header_encoding' => 'BASE64', 73504fd306cSNickeau 'mail_body_encoding' => 'BASE64', 73604fd306cSNickeau 'illegal_chars' => 0, 73704fd306cSNickeau 'encoding_translation' => 'Off', 73804fd306cSNickeau 'language' => self::$language, 73904fd306cSNickeau 'detect_order' => self::$encodingList, 74004fd306cSNickeau 'substitute_character' => 'none', 74104fd306cSNickeau 'strict_detection' => 'Off', 74204fd306cSNickeau ]; 74304fd306cSNickeau 74404fd306cSNickeau if ('all' === $type) { 74504fd306cSNickeau return $info; 74604fd306cSNickeau } 74704fd306cSNickeau if (isset($info[$type])) { 74804fd306cSNickeau return $info[$type]; 74904fd306cSNickeau } 75004fd306cSNickeau 75104fd306cSNickeau return false; 75204fd306cSNickeau } 75304fd306cSNickeau 75404fd306cSNickeau public static function mb_http_input($type = '') 75504fd306cSNickeau { 75604fd306cSNickeau return false; 75704fd306cSNickeau } 75804fd306cSNickeau 75904fd306cSNickeau public static function mb_http_output($encoding = null) 76004fd306cSNickeau { 76104fd306cSNickeau return null !== $encoding ? 'pass' === $encoding : 'pass'; 76204fd306cSNickeau } 76304fd306cSNickeau 76404fd306cSNickeau public static function mb_strwidth($s, $encoding = null) 76504fd306cSNickeau { 76604fd306cSNickeau $encoding = self::getEncoding($encoding); 76704fd306cSNickeau 76804fd306cSNickeau if ('UTF-8' !== $encoding) { 769*83c68632SNico $s = iconv($encoding, 'UTF-8//IGNORE', $s); 77004fd306cSNickeau } 77104fd306cSNickeau 77204fd306cSNickeau $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); 77304fd306cSNickeau 774*83c68632SNico return ($wide << 1) + iconv_strlen($s, 'UTF-8'); 77504fd306cSNickeau } 77604fd306cSNickeau 77704fd306cSNickeau public static function mb_substr_count($haystack, $needle, $encoding = null) 77804fd306cSNickeau { 77904fd306cSNickeau return substr_count($haystack, $needle); 78004fd306cSNickeau } 78104fd306cSNickeau 78204fd306cSNickeau public static function mb_output_handler($contents, $status) 78304fd306cSNickeau { 78404fd306cSNickeau return $contents; 78504fd306cSNickeau } 78604fd306cSNickeau 78704fd306cSNickeau public static function mb_chr($code, $encoding = null) 78804fd306cSNickeau { 78904fd306cSNickeau if (0x80 > $code %= 0x200000) { 79004fd306cSNickeau $s = \chr($code); 79104fd306cSNickeau } elseif (0x800 > $code) { 79204fd306cSNickeau $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F); 79304fd306cSNickeau } elseif (0x10000 > $code) { 79404fd306cSNickeau $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); 79504fd306cSNickeau } else { 79604fd306cSNickeau $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); 79704fd306cSNickeau } 79804fd306cSNickeau 79904fd306cSNickeau if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { 80004fd306cSNickeau $s = mb_convert_encoding($s, $encoding, 'UTF-8'); 80104fd306cSNickeau } 80204fd306cSNickeau 80304fd306cSNickeau return $s; 80404fd306cSNickeau } 80504fd306cSNickeau 80604fd306cSNickeau public static function mb_ord($s, $encoding = null) 80704fd306cSNickeau { 80804fd306cSNickeau if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { 80904fd306cSNickeau $s = mb_convert_encoding($s, 'UTF-8', $encoding); 81004fd306cSNickeau } 81104fd306cSNickeau 81204fd306cSNickeau if (1 === \strlen($s)) { 81304fd306cSNickeau return \ord($s); 81404fd306cSNickeau } 81504fd306cSNickeau 81604fd306cSNickeau $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0; 81704fd306cSNickeau if (0xF0 <= $code) { 81804fd306cSNickeau return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80; 81904fd306cSNickeau } 82004fd306cSNickeau if (0xE0 <= $code) { 82104fd306cSNickeau return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80; 82204fd306cSNickeau } 82304fd306cSNickeau if (0xC0 <= $code) { 82404fd306cSNickeau return (($code - 0xC0) << 6) + $s[2] - 0x80; 82504fd306cSNickeau } 82604fd306cSNickeau 82704fd306cSNickeau return $code; 82804fd306cSNickeau } 82904fd306cSNickeau 830*83c68632SNico public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null): string 831*83c68632SNico { 832*83c68632SNico if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { 833*83c68632SNico throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); 834*83c68632SNico } 835*83c68632SNico 836*83c68632SNico if (null === $encoding) { 837*83c68632SNico $encoding = self::mb_internal_encoding(); 838*83c68632SNico } 839*83c68632SNico 840*83c68632SNico try { 841*83c68632SNico $validEncoding = @self::mb_check_encoding('', $encoding); 842*83c68632SNico } catch (\ValueError $e) { 843*83c68632SNico throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); 844*83c68632SNico } 845*83c68632SNico 846*83c68632SNico // BC for PHP 7.3 and lower 847*83c68632SNico if (!$validEncoding) { 848*83c68632SNico throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); 849*83c68632SNico } 850*83c68632SNico 851*83c68632SNico if (self::mb_strlen($pad_string, $encoding) <= 0) { 852*83c68632SNico throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'); 853*83c68632SNico } 854*83c68632SNico 855*83c68632SNico $paddingRequired = $length - self::mb_strlen($string, $encoding); 856*83c68632SNico 857*83c68632SNico if ($paddingRequired < 1) { 858*83c68632SNico return $string; 859*83c68632SNico } 860*83c68632SNico 861*83c68632SNico switch ($pad_type) { 862*83c68632SNico case \STR_PAD_LEFT: 863*83c68632SNico return self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding).$string; 864*83c68632SNico case \STR_PAD_RIGHT: 865*83c68632SNico return $string.self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding); 866*83c68632SNico default: 867*83c68632SNico $leftPaddingLength = floor($paddingRequired / 2); 868*83c68632SNico $rightPaddingLength = $paddingRequired - $leftPaddingLength; 869*83c68632SNico 870*83c68632SNico return self::mb_substr(str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding).$string.self::mb_substr(str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding); 871*83c68632SNico } 872*83c68632SNico } 873*83c68632SNico 87404fd306cSNickeau private static function getSubpart($pos, $part, $haystack, $encoding) 87504fd306cSNickeau { 87604fd306cSNickeau if (false === $pos) { 87704fd306cSNickeau return false; 87804fd306cSNickeau } 87904fd306cSNickeau if ($part) { 88004fd306cSNickeau return self::mb_substr($haystack, 0, $pos, $encoding); 88104fd306cSNickeau } 88204fd306cSNickeau 88304fd306cSNickeau return self::mb_substr($haystack, $pos, null, $encoding); 88404fd306cSNickeau } 88504fd306cSNickeau 88604fd306cSNickeau private static function html_encoding_callback(array $m) 88704fd306cSNickeau { 88804fd306cSNickeau $i = 1; 88904fd306cSNickeau $entities = ''; 89004fd306cSNickeau $m = unpack('C*', htmlentities($m[0], \ENT_COMPAT, 'UTF-8')); 89104fd306cSNickeau 89204fd306cSNickeau while (isset($m[$i])) { 89304fd306cSNickeau if (0x80 > $m[$i]) { 89404fd306cSNickeau $entities .= \chr($m[$i++]); 89504fd306cSNickeau continue; 89604fd306cSNickeau } 89704fd306cSNickeau if (0xF0 <= $m[$i]) { 89804fd306cSNickeau $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; 89904fd306cSNickeau } elseif (0xE0 <= $m[$i]) { 90004fd306cSNickeau $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; 90104fd306cSNickeau } else { 90204fd306cSNickeau $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80; 90304fd306cSNickeau } 90404fd306cSNickeau 90504fd306cSNickeau $entities .= '&#'.$c.';'; 90604fd306cSNickeau } 90704fd306cSNickeau 90804fd306cSNickeau return $entities; 90904fd306cSNickeau } 91004fd306cSNickeau 91104fd306cSNickeau private static function title_case(array $s) 91204fd306cSNickeau { 91304fd306cSNickeau return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8'); 91404fd306cSNickeau } 91504fd306cSNickeau 91604fd306cSNickeau private static function getData($file) 91704fd306cSNickeau { 91804fd306cSNickeau if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) { 91904fd306cSNickeau return require $file; 92004fd306cSNickeau } 92104fd306cSNickeau 92204fd306cSNickeau return false; 92304fd306cSNickeau } 92404fd306cSNickeau 92504fd306cSNickeau private static function getEncoding($encoding) 92604fd306cSNickeau { 92704fd306cSNickeau if (null === $encoding) { 92804fd306cSNickeau return self::$internalEncoding; 92904fd306cSNickeau } 93004fd306cSNickeau 93104fd306cSNickeau if ('UTF-8' === $encoding) { 93204fd306cSNickeau return 'UTF-8'; 93304fd306cSNickeau } 93404fd306cSNickeau 93504fd306cSNickeau $encoding = strtoupper($encoding); 93604fd306cSNickeau 93704fd306cSNickeau if ('8BIT' === $encoding || 'BINARY' === $encoding) { 93804fd306cSNickeau return 'CP850'; 93904fd306cSNickeau } 94004fd306cSNickeau 94104fd306cSNickeau if ('UTF8' === $encoding) { 94204fd306cSNickeau return 'UTF-8'; 94304fd306cSNickeau } 94404fd306cSNickeau 94504fd306cSNickeau return $encoding; 94604fd306cSNickeau } 94704fd306cSNickeau} 948