Pregunta

Hola Estoy tratando de almacenar los nombres en una base de datos Oracle y traerlos de vuelta usando PHP y oci8.

Sin embargo, si inserto el é directamente en la base de datos Oracle y uso oci8 a buscar de nuevo acabo de recibir una e

¿Tengo que codificar todos los caracteres especiales (incluyendo é) en HTML entidades? (Es decir: é) antes de insertar en la base de datos ... o estoy perdiendo algo

Thx


ACTUALIZACIÓN: mar 1, a 18:40

encontraron esta función: http://www.php.net/manual/en/ function.utf8-decode.php # 85034

function charset_decode_utf_8($string) {
    if(@!ereg("[\200-\237]",$string) && @!ereg("[\241-\377]",$string)) {
        return $string;
    }
$string = preg_replace("/([\340-\357])([\200-\277])([\200-\277])/e","'&#'.((ord('\\1')-224)*4096 + (ord('\\2')-128)*64 + (ord('\\3')-128)).';'",$string);
$string = preg_replace("/([\300-\337])([\200-\277])/e","'&#'.((ord('\\1')-192)*64+(ord('\\2')-128)).';'",$string);
return $string;
}

Parece que funciona, aunque no estoy seguro si es la solución óptima


ACTUALIZACIÓN: 8 Mar a las 15:45

conjunto de caracteres de Oracle es ISO-8859-1.
en PHP añadí:

putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1");

para forzar la conexión oci8 utilizar ese juego de caracteres. Recuperando el é usando oci8 desde PHP ahora funcionado! (Por varchars, pero no CLOBs tenido que hacer utf8_encode para extraerlo)
Así Luego trató de guardar los datos de PHP para Oracle ... y es imposible work..somewhere a lo largo del camino desde PHP a Oracle la é se convierte en un ?


ACTUALIZACIÓN: 9 Mar a las 14:47

Así que cada vez más cerca. Después de añadir la variable NLS_LANG, haciendo inserciones oci8 directos con obras é.

El problema es en realidad en el lado de PHP. Mediante el uso de marco ExtJs, al enviar un formulario que lo codifica utilizando encodeURIComponent.
Así é se envía como %C3%A9 y luego re-codificado en é.
Sin embargo, de la longitud es ahora 2 (strlen($my_sent_value) = 2) y no 1. Y si en PHP Trato: $ my_sent_value == é = false

Creo que si soy capaz de volver a codificar todos estos personajes en la parte trasera de PHP en trozos de tamaño en bytes 1 y luego insertarlos en Oracle, que debería funcionar.

Todavía no hay suerte, aunque


ACTUALIZACIÓN 10 marzo a las 11:05

No dejo de pensar que estoy tan cerca (pero tan lejos).

putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P9"); funciona muy sporadicly.

He creado un pequeño script php para la prueba:

header('Content-Type: text/plain; charset=ISO-8859-1');
putenv("NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P9");
$conn= oci_connect("user", "pass", "DB");
$stmt = oci_parse($conn, "UPDATE temp_tb SET string_field = '|é|'");
oci_execute($stmt, OCI_COMMIT_ON_SUCCESS);

Después de ejecutar esto de una vez autenticarte en la base de datos de Oracle directamente veo que STRING_FIELD se establece en |¿|. Obviamente no es lo que había llegado a esperar de mi experiencia anterior.
Sin embargo, si me refresque la página PHP dos veces rápidamente .... funcionó !!!
En Oracle vi correctamente |é|.

Parece que tal vez la variable de entorno no se establece o se envía a tiempo para la primera ejecución del script correctamente, pero está disponible para la segunda ejecución.

Mi siguiente experimento es exportar la variable en el entorno de PHP, sin embargo, tengo que reiniciar Apache para que ... así que ya veremos lo que pasa, es de esperar que funciona.

¿Fue útil?

Solución 2

Esto es lo que finalmente terminó haciendo para resolver este problema:

Modificado el perfil del demonio que se ejecuta PHP tener:

NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1

Para que la conexión oci8 utiliza ISO-8859-1.

A continuación, en la configuración de mi PHP establecer el tipo de contenido predeterminado a ISO-8859-1:

default_charset = "iso-8859-1"

Cuando Estoy insertando en una tabla de Oracle a través de oci8 desde PHP, lo hago:

utf8_decode($my_sent_value)

Y cuando se reciben datos de Oracle, la impresión de la variable sólo debe funcionar como tal:

echo $my_received_value

Sin embargo, cuando el envío de datos a través de ajax que he tenido que usar:

utf8_encode($my_received_value)

Otros consejos

supongo que son conscientes de estos hechos:

  • Hay muchos diferentes juegos de caracteres: usted tiene que escoger uno y, por supuesto, sabe que uno está utilizando
  • .
  • Oracle es perfectamente capaz de almacenar texto sin HTML entidades (é). entidades HTML se utilizan en, bueno, HTML. Oracle no es un navegador web; -)

También debe saber que el HTML entidades no se unen a un juego de caracteres específico; por el contrario, se usan para representar los caracteres en un contexto charset-independiente.

indistintamente habla de la norma ISO-8859-1 y UTF-8. Qué hacer juego de caracteres que desea utilizar? ISO-8859-1 es fácil de usar, pero sólo puede almacenar texto en algunas lenguas latinas (como el español) y que carece de algunos caracteres comunes como el símbolo €. UTF-8 es más difícil de usar, pero puede almacenar todos los caracteres definidos por el consorcio Unicode (que incluyen todo lo que necesitas).

Una vez que haya tomado la decisión, debe configurar Oracle para datos tenemos en tan charset y elegir un tipo de columna correspondiente. Por ejemplo, VARCHAR2 está muy bien para ASCII, NVARCHAR2 es bueno para UTF-8.

Si realmente no puede cambiar el juego de caracteres que Oracle utilizará entonces ¿qué codificación Base64 sus datos antes de almacenarlos en la base de datos. De esta manera, se puede aceptar caracteres de cualquier conjunto de caracteres y guardarlas como ISO-8859-1 (porque Base 64 es la salida de un subconjunto del conjunto de caracteres ASCII que hace corresponder exactamente a la norma ISO-8859-1). Codificación Base64 aumentará la longitud de la cadena por, en promedio, 37%

Si los datos son sólo alguna vez va a ser visualizado como HTML, entonces puede ser que también almacenar las entidades HTML como usted sugiere, pero tenga en cuenta que una sola entidad puede ser de hasta 10 caracteres por caracteres sin codificar, por ejemplo, θ es decir ϑ

he tenido que hacer frente a este problema: "?" Los caracteres especiales se almacenan como latinoamericanos o "¿" en mi base de datos Oracle ... No puedo cambiar la NLS_CHARACTER_SET porque no somos los propietarios de bases de datos.

Por lo tanto, he encontrado una solución:

1) código ASP.NET Crear una función que convierte a la cadena de caracteres hexadecimales:

    public string ConvertirStringAHex(String input)
    {
        Encoding encoding = System.Text.Encoding.GetEncoding("ISO-8859-1");
        Byte[] stringBytes = encoding.GetBytes(input);
        StringBuilder sbBytes = new StringBuilder(stringBytes.Length);
        foreach (byte b in stringBytes)
        {
            sbBytes.AppendFormat("{0:X2}", b);
        }
        return sbBytes.ToString();
    }

2) Aplicar la función anterior a la variable que desea codificar, como esto

     myVariableHex = ConvertirStringZHex( myVariable );

En ORACLE, utilice el siguiente:

 PROCEDURE STORE_IN_TABLE( iTEXTO IN VARCHAR2 )
 IS
 BEGIN
   INSERT INTO myTable( SPECIAL_TEXT )  
   VALUES ( UTL_RAW.CAST_TO_VARCHAR2(HEXTORAW( iTEXTO ));
   COMMIT;
 END;

Por supuesto, iTEXTO es el parámetro de Oracle que recibe el valor de "myVariableHex" de código ASP.NET.

Espero que ayuda ... si hay algo para mejorar pls no dude en enviar sus comentarios.

Fuentes: http: / /www.nullskull.com/faq/834/convert-string-to-hex-and-hex-to-string-in-net.aspx https://forums.oracle.com/thread/44799

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top