UTF-8 equivalente seguro de ord o charCodeAt () en PHP

Necesito poder usar ord () para obtener el mismo valor que la función charCodeAt () de JavaScript. El problema es que ord () no es compatible con UTF8.

¿Cómo puedo obtener Ą para traducir a 260 en PHP? He intentado algunas funciones uniord, pero todas informan 256 en lugar de 260.

¡Muchas gracias por cualquier ayuda!

Saludos

ord() trabaja byte por byte (como la mayoría de las funciones de cadena estándar de PHP, si no todas). Debería convertirlo usted mismo, por ejemplo con la ayuda de la extensión de cadena multibyte:

 $utf8Character = 'Ą'; list(, $ord) = unpack('N', mb_convert_encoding($utf8Character, 'UCS-4BE', 'UTF-8')); echo $ord; # 260 

Versión mbstring:

 function utf8_char_code_at($str, $index) { $char = mb_substr($str, $index, 1, 'UTF-8'); if (mb_check_encoding($char, 'UTF-8')) { $ret = mb_convert_encoding($char, 'UTF-32BE', 'UTF-8'); return hexdec(bin2hex($ret)); } else { return null; } } 

usando htmlspecialchars y htmlspecialchars_decode para obtener un personaje:

 function utf8_char_code_at($str, $index) { $char = ''; $str_index = 0; $str = utf8_scrub($str); $len = strlen($str); for ($i = 0; $i < $len; $i += 1) { $char .= $str[$i]; if (utf8_check_encoding($char)) { if ($str_index === $index) { return utf8_ord($char); } $char = ''; $str_index += 1; } } return null; } function utf8_scrub($str) { return htmlspecialchars_decode(htmlspecialchars($str, ENT_SUBSTITUTE, 'UTF-8')); } function utf8_check_encoding($str) { return $str === utf8_scrub($str); } function utf8_ord($char) { $lead = ord($char[0]); if ($lead < 0x80) { return $lead; } else if ($lead < 0xE0) { return (($lead & 0x1F) << 6) | (ord($char[1]) & 0x3F); } else if ($lead < 0xF0) { return (($lead & 0xF) << 12) | ((ord($char[1]) & 0x3F) << 6) | (ord($char[2]) & 0x3F); } else { return (($lead & 0x7) << 18) | ((ord($char[1]) & 0x3F) << 12) | ((ord($char[2]) & 0x3F) << 6) | (ord($char[3]) & 0x3F); } } 

Versión de extensión de PHP:

 #include "ext/standard/html.h" #include "ext/standard/php_smart_str.h" const zend_function_entry utf8_string_functions[] = { PHP_FE(utf8_char_code_at, NULL) PHP_FE_END }; PHP_FUNCTION(utf8_char_code_at) { char *str; int len; long index; unsigned int code_point; long i; int status; size_t pos = 0, old_pos = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &str, &len, &index) == FAILURE) { return; } for (i = 0; pos < len; ++i) { old_pos = pos; code_point = php_next_utf8_char((const unsigned char *) str, (size_t) len, &pos, &status); if (i == index) { if (status == SUCCESS) { RETURN_LONG(code_point); } else { RETURN_NULL(); } } } RETURN_NULL(); } 

Tratar:

 function uniord($c) { $h = ord($c{0}); if ($h <= 0x7F) { return $h; } else if ($h < 0xC2) { return false; } else if ($h <= 0xDF) { return ($h & 0x1F) << 6 | (ord($c{1}) & 0x3F); } else if ($h <= 0xEF) { return ($h & 0x0F) << 12 | (ord($c{1}) & 0x3F) << 6 | (ord($c{2}) & 0x3F); } else if ($h <= 0xF4) { return ($h & 0x0F) << 18 | (ord($c{1}) & 0x3F) << 12 | (ord($c{2}) & 0x3F) << 6 | (ord($c{3}) & 0x3F); } else { return false; } } echo uniord('Ą'); 

Esto debería ser el equivalente al código de charCodeAt() de JavaScript charCodeAt() basado en el trabajo de @ hakre, pero corregido para que realmente funcione igual que JavaScript (en todos los sentidos que se me ocurra probar):

 function charCodeAt($string, $offset) { $string = substr($string, $offset, 1); list(, $ret) = unpack('S', mb_convert_encoding($character, 'UTF-16LE')); return $ret; } 

Hay una función ord_utf8 aquí: https://stackoverflow.com/a/42600959/7558876

Esta función se ve así (aceptar cadena y número entero devuelto)

 239&&$s[2]>127&&$s[3]>127&&$s[4]>127?(7&$s[1])<<18|(63&$s[2])<<12|(63&$s[3])<<6|63&$s[4]: ($s[1]>223&&$s[2]>127&&$s[3]>127?(15&$s[1])<<12|(63&$s[2])<<6|63&$s[3]: ($s[1]>193&&$s[2]>127?(31&$s[1])<<6|63&$s[2]:0))); } 

Y una rápida chr_utf8 aquí: https://stackoverflow.com/a/42510129/7558876

Esta función se ve así (acepta un entero y devuelve una cadena)

 >6,1<<7|191&$n): ($n<(1<<16)?pack($f,224|$n>>12,1<<7|63&$n>>6,1<<7|63&$n): ($n<(1<<20|1<<16)?pack($f,240|$n>>18,1<<7|63&$n>>12,1<<7|63&$n>>6,1<<7|63&$n):''))); } 

Por favor revisa los enlaces si quieres un ejemplo ...