• Publicidad

use UTF8, utf8 NO BOM y librerías

Todo lo relacionado con el desarrollo Web con Perl: desde CGI hasta Mojolicious

use UTF8, utf8 NO BOM y librerías

Notapor lr_emilio » 2013-08-01 12:31 @563

Hola,

Mi problema son los caracteres raros a la hora de imprimir un archivo html en el navegador. Detallo a continuación:

Tengo una función en un archivo .pl que imprime un documento html.

A la función se le llama así Lehtm("archivo.htm","variable1","variable2"...);

La función lo que hace es leer un archivo .html línea a línea y sustituye donde encuentra §S1§ por la variable variable1, §S2§ por la variable variable2, luego imprime por pantalla el html con las sustituciones.

La función finaliza de la siguiente forma: (como veis lleva el charset utf8).

print <<LIM; #>
content-type: text/html;charset=UTF-8 \n\n
$contenido
LIM
1;
}

Este archivo .pl donde está esta función está guardado como utf8, sin BOM.

Si pongo en la cabecera del .pl el use utf8 y el use encode me saltan errores por todos lados.


Hasta ahora siempre había trabajado con latin haciendo aplicaciones web. Tengo varias librerías hechas que tienen funciones especificas para consultar y modificar bases de datos. Los archivos .html los guardaba en formato DOS y los .pl los guardaba en formato UNIX. siempre en ASCII.

El problema es que ahora quiero trabajar en utf8. Me he estado leyendo tutoriales y tengo las cosas más o menos claras aunque algo no estoy cogiendo y por eso acudo a vosotros.

Trabajo con Perl 5.8.8 y MySQL.

- Las bases, tablas y campos los tengo en utf8_general_ci.
- tengo declarados en todos los archivos .html el charset utf8 y todos los html los tengo guardados en formato utf8, sin BOM.
- todos los archivos .pl están guardados en formato utf8, sin BOM.
lr_emilio
Perlero nuevo
Perlero nuevo
 
Mensajes: 25
Registrado: 2013-08-01 11:57 @539

Publicidad

Re: use UTF8, utf8 NO BOM y librerías

Notapor explorer » 2013-08-01 15:19 @680

Bienvenido a los foros de Perl en Español, lr_emilio.

El use utf8; sirve sólo si en tu código fuente hay caracteres en utf8. Si la información la sacas de base de datos y archivos externos, no te sirve de nada.

Como mandas el charset, entonces lo único que, en teoría, se debería hacer, sería una de estas dos líneas

binmode(STDOUT, ':encoding(UTF-8)'); # Perl hace una comprobación de que son datos UTF-8, de forma estricta

binmode(STDOUT, ':utf8'); # Perl admite los datos como que son UTF-8, sin comprobar

antes de imprimir. Más información en perldoc -f binmode

Pero... también hay que tener en cuenta en qué están codificados los datos que recibes desde la base de datos. Dices que están en utf8, pero Perl no lo sabe.

Entonces... el proceso general es: todo dato externo que llegue al programa, le decimos a Perl en qué codificación está. Eso lo podemos hacer con un binmode() (en caso de leer de un archivo) o con alguna de las funciones del módulo Encode, en caso de recibirlos desde la base de datos.

A partir de ese momento, Perl sabe que tiene cadenas de caracteres codificadas en Unicode. Y solo queda sacarlas fuera. Tenemos que decirle a Perl que esos datos en Unicode debe pasarlos a UTF-8. Por eso ponemos el binmode anterior, referido al STDOUT.

Más información y ejemplos en Modern Perl, página 18.

Recomendable usar un Perl v5.12 o superior, pues incluye una característica nueva: "unicode_strings", que permite realizar operaciones con variables que contienen caracteres Unicode. Mejor aún: usar Perl v5.14 o superior.

Más información en tu propio ordenador en perldoc perluniintro, y en la Web.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: use UTF8, utf8 NO BOM y librerías

Notapor lr_emilio » 2013-08-02 06:43 @322

Hola, muchas gracias por la rápida respuesta.

Sigo teniendo problemas en una cosa: lo que imprime por pantalla desde una variable de Perl se muestra correctamente.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $men = "<font class=\"mensaje\"> <br> El usuario y/o el password no coinciden.<br> $ € á é í ó ú Á É Í Ó Ú Inténtelo de nuevo o póngase en contacto con el administrador.</font>";
  2. &LeHtmUTF8("../index2.htm","$men");
  3.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Pero lo que está escrito ya en el archivo .html (guardado en utf8, sin BOM, y con el charset utf8) que lee la función LeeHtmUTF8() lo muestra con caracteres raros.

Detallo lo que he hecho:

He puesto binmode(STDOUT, ':encoding(UTF-8)'); antes del print() de la función LeHtmUTF8() que comentaba más arriba quedando la cosa así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub LeHtmUTF8 {
  2.     $Pagina = $_[0];
  3.     $P      = @_;
  4.  
  5.     $PosBarraV = index( $Pagina, "|" );
  6.     if ( $PosBarraV ne "-1" ) {
  7.         $Pagina = substr( $Pagina, 0, $PosBarraV );
  8.     }
  9.     open( SUST, "$Pagina" ) || die &MensajesErrores(
  10.         "",
  11.         "Error en LeHtm al abrír $Pagina",
  12.         "No se Encuentra, o no tiene permisos adecuados",
  13.         "Parametro:$_[1]", "Parametro:$_[2]", "Parametro:$_[3]"
  14.     );
  15.     @lin_pag = <SUST>;
  16.     close SUST;
  17.     $contenido = join( "", @lin_pag );
  18.     for ( $c = 1; $c < $P; $c++ ) {    #>
  19.         $U = "S$c";
  20.         $V = $_[$c];
  21.         $contenido =~ s/§$U§/$V/g;
  22.     }
  23.     binmode( STDOUT, ':encoding(UTF-8)' );    # Perl hace una comprobación de que son datos UTF-8, de forma estricta
  24.     print <<LIM;                              #>
  25. content-type: text/html;charset=UTF-8 \n\n
  26. $contenido
  27. LIM
  28.     1;
  29. }
  30.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Ahora, según te he entendido, tengo que decirle a Perl en qué codificación está el fichero .html que voy a leer.

Si pongo esto me falla. ¿Podría ser por la versión de Perl que uso, la v5.8.8?
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open (SUST,"<:encoding(utf8)","$Pagina")        || die &MensajesErrores("","Error en LeHtm al abrír $Pagina","No se Encuentra, o no tiene permisos adecuados","Parametro:$_[1]","Parametro:$_[2]","Parametro:$_[3]");
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El funcionamiento de la web de prueba que estoy haciendo es esta:

Entro en el index de una web que tiene un formulario de login.
Cuando hago el submit va a un archivo .pl para comprobar el acceso.
Si el login es incorrecto llamo a la función LeHtmUTF8 de la siguiente forma:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $men = "<font class=\"mensaje\"> <br> El usuario y/o el password no coinciden.<br> $ € á é í ó ú Á É Í Ó Ú Inténtelo de nuevo o póngase en contacto con el administrador.</font>";
  2. &LeHtmUTF8("../index2.htm","$men");
  3.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


index2.html tiene tildes ya en el propio archivo y éstos son los que se ven mal cuando imprimo con LeHtmUTF8.
En cambio, los que paso en la variable $men se muestran correctamente.

A ver si me he explicado ... ¡je, je!

Muchas gracias.
lr_emilio
Perlero nuevo
Perlero nuevo
 
Mensajes: 25
Registrado: 2013-08-01 11:57 @539

Re: use UTF8, utf8 NO BOM y librerías

Notapor explorer » 2013-08-02 07:32 @356

lr_emilio escribiste:lo que imprime por pantalla desde una variable de Perl se muestra correctamente.
Eso es porque usas el 'use utf8;'.

lr_emilio escribiste:Pero lo que está escrito ya en el archivo .html (guardado en utf8, sin BOM, y con el charset utf8) que lee la función LeeHtmUTF8() lo muestra con caracteres raros.
¿Son "raros" o están duplicados? Por favor, copialos aquí, para que los veamos.

lr_emilio escribiste:¿Podría ser por la versión de Perl que uso, la v5.8.8?
Lo has puesto bien, y la forma de comprobarlo es imprimir $Pagina justo después del open(), para comprobar que lo lee bien en UTF8 (pon el binmode() antes de ese print()).

lr_emilio escribiste:index2.html tiene tildes ya en el propio archivo y éstos son los que se ven mal cuando imprimo con LeHtmUTF8.
En cambio, los que paso en la variable $men se muestran correctamente.
Entonces, ocurre que no está leyéndolo bien en UTF8, o que las operaciones intermedias (línea 21, la expresión regular) destrozan esa codificación, como se comenta en la página 21 de Modern Perl.

La versión de Perl v5.8.8 sí que es algo antigua... ¡siete años!

Lo dicho: haz una prueba:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. open(SUST, '<:encoding(UTF-8)', $Pagina) or die;
  2. {
  3.     locale $/;                # modo aspiradora
  4.     my $contenido = <SUST>;   # ¡shuuuuup!
  5.  
  6.     binmode(STDOUT, ':encoding(UTF-8)');
  7.     print "Content-type: text/html;charset=UTF-8\n\n";
  8.     print $contenido;
  9. }
  10. close SUST;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
y nos dices si salen bien los caracteres tildados o no.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: use UTF8, utf8 NO BOM y librerías

Notapor lr_emilio » 2013-08-02 19:42 @863

Muchas gracias, explorer.

El lunes, cuando llegue al trabajo, lo pruebo y os comento.

Un saludo.
lr_emilio
Perlero nuevo
Perlero nuevo
 
Mensajes: 25
Registrado: 2013-08-01 11:57 @539

Re: use UTF8, utf8 NO BOM y librerías

Notapor lr_emilio » 2013-08-05 02:51 @160

explorer escribiste:¿Son "raros" o están duplicados? Por favor, copialos aquí, para que los veamos.


Esto es lo que muestra el navegador:


Sintáxis: [ Descargar ] [ Ocultar ]
Using html4strict Syntax Highlighting
  1. Esta aplicación está optimizada para .......
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4



ahora probaré el resto.


Un saludo y gracias.
lr_emilio
Perlero nuevo
Perlero nuevo
 
Mensajes: 25
Registrado: 2013-08-01 11:57 @539

Re: use UTF8, utf8 NO BOM y librerías

Notapor lr_emilio » 2013-08-05 05:35 @274

He cambiado la función a esta para probar:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub LeHtmUTF8{
  2. $Pagina=$_[0];
  3. open(SUST, '<:encoding(UTF-8)', $Pagina) or die;
  4. {
  5.     locale $/;                # modo aspiradora
  6.     my $contenido = <SUST>;   # ¡shuuuuup!
  7.  
  8.     binmode(STDOUT, ':encoding(UTF-8)');
  9.     print "Content-type: text/html;charset=UTF-8\n\n";
  10.     print $contenido;
  11. }
  12. close SUST;
  13. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


y al hacer el submit del login el navegador me da error de que no se puede mostrar la página.

el log muestra esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
[Mon Aug 05 12:32:35 2013] [error] [client 213.60.47.155] Malformed UTF-8 character (unexpected continuation byte 0x82, with no preceding start byte) at /home/acpack/public_html/cgi-bin/Bitacora_Acceso.pl line 83., referer: http://*****.es/index1.htm
[Mon Aug 05 12:32:35 2013] [error] [client 213.60.47.155] Malformed UTF-8 character (unexpected continuation byte 0xac, with no preceding start byte) at /home/acpack/public_html/cgi-bin/Bitacora_Acceso.pl line 83., referer: http://acpack.enlared.es/index1.htm
[Mon Aug 05 12:32:35 2013] [error] [client 213.60.47.155] Can't call method "locale" without a package or object reference at /usr/lib/perl5/5.8.8/i386-linux-thread-multi/RutRedUTF8.pl line 402., referer: http://*****.es/index1.htm
[Mon Aug 05 12:32:35 2013] [error] [client 213.60.47.155] Premature end of script headers: Bitacora_Acceso.pl, referer: http://****.es/index1.htm
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4



la línea 83 es esta:
$men = "<font class=\"mensaje\"> <br> El usuario y/o el password no coinciden.<br> $ € á é í ó ú Á É Í Ó Ú Inténtelo de nuevo o póngase en contacto con el administrador.</font>";
lr_emilio
Perlero nuevo
Perlero nuevo
 
Mensajes: 25
Registrado: 2013-08-01 11:57 @539

Re: use UTF8, utf8 NO BOM y librerías

Notapor explorer » 2013-08-05 06:42 @321

Humm... ¿estás seguro de que el código fuente del programa está escrito en UTF-8? ¿Y está puesto el 'use utf8;'?

Si sale un error ahí, es que Perl no está encontrado la codificación correcta en esa línea.

Recuerda que el código fuente debe estar escrito en un editor que entienda UTF-8, y si es en una terminal, ésta también debe estar en ese codificación. Y no importa que el archivo tenga el BOM o no.

Si ves que la codificación es correcta, prueba a quitar caracteres tildados hasta que sepas cuál es el que provoca el fallo.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: use UTF8, utf8 NO BOM y librerías

Notapor lr_emilio » 2013-08-05 09:19 @430

El editor que utilizo es el UltraEdit y es compatible con UTF-8. De hecho, me deja convertir ASCII, UTF-8 y Unicode.

El formato en el que están todos los ficheros es utf-8.

Estoy intentando actualizar la versión de Perl y haré pruebas.

Muchas gracias, explorer.
lr_emilio
Perlero nuevo
Perlero nuevo
 
Mensajes: 25
Registrado: 2013-08-01 11:57 @539

Re: use UTF8, utf8 NO BOM y librerías

Notapor lr_emilio » 2013-08-05 12:09 @548

Hola,

he estado haciendo pruebas y he puesto lo siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub LeHtmUTF8{
  2. $Pagina=$_[0];
  3. open(SUST, '<:encoding(UTF-8)', $Pagina) or die;
  4. my $contenido = <SUST>;
  5. close SUST;
  6. binmode(STDOUT, ':encoding(UTF-8)');
  7. print "Content-type: text/html;charset=UTF-8\n\n";
  8. print $contenido;
  9. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


No me da ningún error el log pero la respuesta de $contenido es ésta, según Firebug (una página en blanco):
Sintáxis: [ Descargar ] [ Ocultar ]
Using html4strict Syntax Highlighting
  1. <!DOCTYPE html>
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
lr_emilio
Perlero nuevo
Perlero nuevo
 
Mensajes: 25
Registrado: 2013-08-01 11:57 @539

Siguiente

Volver a Web

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 11 invitados

cron