2010-09-13 19 views
7

Dado un número hexadecimal o decimal Unicode para un personaje que desea generar un script CLI PHP, ¿cómo puede PHP generarlo? La función chr() parece no generar el resultado correcto. Aquí está mi script de prueba, utilizando el carácter de salto de sección U + 00A7 (A7 en hexadecimal, 167 en decimal, debe ser representado como C2 A7 en UTF-8) como una prueba:PHP construir una cadena Unicode?

<?php 
echo "Section sign: ".chr(167)."\n"; // Using CHR function 
echo "Section sign: ".chr(0xA7)."\n"; 
echo "Section sign: ".pack("c", 0xA7)."\n"; // Using pack function? 
echo "Section sign: §\n"; // Copy and paste of the symbol into source code 

La salida consigo (a través una sesión de SSH al servidor) es:

lo tanto, que demuestra que la fuente de terminal que estoy usando tiene el carácter de salto de sección en ella, y la conexión SSH está enviarlo junto con éxito, pero chr() ISN' t construirlo correctamente al construirlo a partir del número de código.

Si todo lo que tengo es el número de código y no una opción de copiar/pegar, ¿qué opciones tengo?

Respuesta

4

PHP no tiene conocimiento de Unicode al excluir las funciones mb_ y iconv. Tendrás que UTF-8 para codificar el personaje tú mismo.

Para eso, Wikipedia tiene un excellent overview sobre cómo se estructura el UTF-8. Aquí está una función rápida, sucio y no probado basado en ese artículo:

function codepointToUtf8($codepoint) 
{ 
    if ($codepoint < 0x7F) // U+0000-U+007F - 1 byte 
     return chr($codepoint); 
    if ($codepoint < 0x7FF) // U+0080-U+07FF - 2 bytes 
     return chr(0xC0 | ($codepoint >> 6)).chr(0x80 | ($codepoint & 0x3F); 
    if ($codepoint < 0xFFFF) // U+0800-U+FFFF - 3 bytes 
     return chr(0xE0 | ($codepoint >> 12)).chr(0x80 | (($codepoint >> 6) & 0x3F).chr(0x80 | ($codepoint & 0x3F); 
    else // U+010000-U+10FFFF - 4 bytes 
     return chr(0xF0 | ($codepoint >> 18)).chr(0x80 | ($codepoint >> 12) & 0x3F).chr(0x80 | (($codepoint >> 6) & 0x3F).chr(0x80 | ($codepoint & 0x3F); 
} 
+0

Una forma excelente de hacerlo sería simplemente escribir el documento PHP en UTF-8 en primer lugar. –

+0

Excelente respuesta, Michael; y gracias por la función! Creé algo similar para mí usando la función pack en lugar de chr repetidamente. Billy, para este propósito específico, necesito pasar de un punto de código a un personaje; escribir el script PHP en UTF-8 con los caracteres ya integrados no es una opción. – MidnightLightning

3

No olvide que UTF-8 es una codificación de longitud variable.

§ no está incluido en los primeros 128 caracteres (ASCII) que UTF-8 puede mostrar en uno byte. § es un carácter de varios bytes en UTF-8, precedido por un byte c2 que significa first byte of a two-byte sequence.. Esto debería funcionar:

echo "Section sign: ".chr(0xC2).chr(0xA7)."\n"; 
3
chr 

(PHP 4, PHP 5) 

chr — Return a specific character 

Report a bug 
Description 

string chr (int $ascii) 
Returns a one-character string containing the character specified by ascii. 

Esta función complementa ord().

importante es la palabra ASCII :) prueba este:

function uchr ($codes) { 
     if (is_scalar($codes)) $codes= func_get_args(); 
     $str= ''; 
     foreach ($codes as $code) $str.= html_entity_decode('&#'.$code.';',ENT_NOQUOTES,'UTF-8'); 
     return $str; 
    } 
    echo "Section sign: ".uchr(167)."\n"; // Using CHR function 
    echo "Section sign: ".uchr(0xA7)."\n"; 
5

Asumiendo que tiene iconv, he aquí una forma sencilla que no implica la implementación de UTF-8 a sí mismo:

function unichr($i) { 
    return iconv('UCS-4LE', 'UTF-8', pack('V', $i)); 
} 
0

Sé que estoy volviendo a abrir un tema viejo y resuelto, sin embargo, desde que tropecé con ese tema en busca de ayuda, pensé que compartiría la solución con la que terminé. La persona inicial que hace la pregunta puede estar interesada en refaccionar su código al máximo.

La reprogramación manual de ascii-a-unicode es como reinventar la rueda, sin hablar de errores/potencial de rendimiento.

La mejor solución que encontré fue utilizar:

  1. pack para crear valores a partir de los datos de entrada, utilizando los códigos adecuados para comer la cantidad adecuada de datos, por lo general pack("H*", <input data>) leer de valores hexadecimales
  2. mb_convert_encoding para convertir cadenas ASCII a unidades Unicode, usando mb_convert_encoding(<ASCII string>, "UTF-8"). Si la cadena de entrada no se reconoce correctamente, un tercer parámetro de esta función permite especificar la codificación de entrada
Cuestiones relacionadas