127) { // Since the first byte must have the 7th bit set we check that. Otherwise, we might be in the middle of a byte sequence. if ($ord & 64) { // Add first byte $buf = $chr; // For each byte in multibyte string... for ($b = 0; $b < 8; $b++) { // Shift it left and ... $ord <<= 1; // ... and with 8th bit - if that is set, then there are still bytes in sequence. if ($ord & 128) { $a++; // ... and add the next char. $buf .= $str[$a]; } else { break; } } $outArr[] = $buf; } else { $outArr[] = self::FALLBACK_CHAR; } } else { $outArr[] = chr($ord); } } return $outArr; } /** * Converts a UTF-8 Multibyte character to a UNICODE number * Unit-tested by Kasper * * @param string $str UTF-8 multibyte character string * @param bool $hex If set, then a hex. number is returned. * @return ($hex is false ? int : string) UNICODE integer */ public function utf8CharToUnumber(string $str, bool $hex = false): int|string { // First char $ord = ord($str[0]); // This verifies that it IS a multibyte string if (($ord & 192) === 192) { $binBuf = ''; $b = 0; // For each byte in multibyte string... for (; $b < 8; $b++) { // Shift it left and ... $ord <<= 1; // ... and with 8th bit - if that is set, then there are still bytes in sequence. if ($ord & 128) { $binBuf .= substr('00000000' . decbin(ord($str[$b + 1])), -6); } else { break; } } $binBuf = substr('00000000' . decbin(ord($str[0])), -(6 - $b)) . $binBuf; $int = bindec($binBuf); } else { $int = $ord; } return $hex ? 'x' . dechex((int)$int) : $int; } /** * Maps all characters of a UTF-8 string. * * @param string $str UTF-8 string */ public function utf8_char_mapping(string $str): string { $out = ''; for ($i = 0; isset($str[$i]); $i++) { $c = ord($str[$i]); $mbc = ''; // single-byte (0xxxxxx) if (!($c & 128)) { $mbc = $str[$i]; } elseif (($c & 192) === 192) { $bc = 0; // multibyte starting byte (11xxxxxx) for (; $c & 128; $c <<= 1) { $bc++; } // calculate number of bytes $mbc = substr($str, $i, $bc); $i += $bc - 1; } if ($this->charsetProvider->hasMultibyteChar('utf-8', $mbc)) { $out .= $this->charsetProvider->getByMultibyteChar('utf-8', $mbc); } else { $out .= $mbc; } } return $out; } }