Firma UTF-8 BOM en archivos PHP

9 minutos de lectura

Firma UTF 8 BOM en archivos PHP
treznik

Estaba escribiendo algunas clases de PHP comentadas y me topé con un problema. Mi nombre (para la etiqueta @author) termina con un ș (que es un carácter UTF-8, … y un nombre extraño, lo sé).

A pesar de que guardo el archivo como UTF-8, algunos amigos informaron que ven a ese personaje totalmente desordenado (È™). Este problema desaparece al agregar la firma BOM. Pero eso me preocupa un poco, ya que no sé mucho al respecto, excepto por lo que vi en Wikipedia y en algunas otras preguntas similares aquí en SO.

Sé que agrega algunas cosas al comienzo del archivo y, por lo que entendí, no es tan malo, pero estoy preocupado porque los únicos escenarios problemáticos que leí sobre archivos PHP involucrados. Y como estoy escribiendo clases de PHP para compartirlas, ser 100% compatible es más importante que tener mi nombre en los comentarios.

Pero estoy tratando de entender las implicaciones, ¿debería usarlo sin preocuparme? o hay casos en los que podría causar daños? ¿Cuándo?

  • Tenga en cuenta que hoy estaba teniendo un problema donde un <?php die('test') en la parte superior de un archivo PHP incluido se mostraba la lista de materiales UTF-8 (estos caracteres: ) en la parte superior del archivo. Fue difícil de averiguar. Fue entonces cuando descubrí que uno de los desarrolladores guardó el archivo en Unicode, no en ASCII, y este PHP no podía leer archivos PHP Unicodificados. Comencé una copia nueva, copié los datos y los guardé en ASCII, y el problema se resolvió. Tenga en cuenta que algunos programas FTP pueden hacerle esto, si alguna vez se encuentra con esto.

    – Volomike

    14 mayo 2012 a las 15:12

  • Tenga en cuenta también que las variables de sesión no parecen funcionar correctamente en las páginas cuando una página tiene este problema de BOM UTF-8. Tuve que usar un editor hexadecimal como ghex en Ubuntu plus iconv -f utf8 -t ascii old.php > new.php repetidamente para detectar todos los problemas de Unicode, elimínelos y guarde la página finalmente en ASCII sin errores desde el comando iconv. Una vez hecho esto, noté que las variables de sesión se mantenían en estado entre páginas.

    – Volomike

    14 mayo 2012 a las 15:50

  • Parece que cuando se detecta UTF-8 BOM en un archivo, nunca se envían encabezados que mantengan la sesión y, por lo tanto, las variables de sesión entre páginas obtendrán sesiones completamente nuevas en lugar de mantener la misma sesión.

    – Volomike

    14 mayo 2012 a las 16:00

  • no es que PHP “detecte” el BOM y, si está presente, “decida” descartar las variables de sesión; el problema es que PHP (al menos he visto versiones que hacen esto) lee el archivo, lee una ï, lo imprime, lee un », lo imprime, lee un ¿, lo imprime… el problema ahora es que session_start() provoca alguna comunicación de encabezado, que solo puede ocurrir mientras todavía estamos en la fase de comunicación de encabezado, y la impresión de algo termina esta fase si hubiera configurado la variable ini “display_errors” en “On”, recibiría un mensaje que le indicaría que session_start ha fallado por este motivo

    – Algomán

    02/02/2016 a las 20:51

De hecho, la lista de materiales son datos reales enviados al navegador. El navegador lo ignorará felizmente, pero aún así no podrá enviar encabezados.

Creo que el problema realmente es la configuración del editor de usted y su amigo. Sin una lista de materiales, es posible que el editor de su amigo no reconozca automáticamente el archivo como UTF-8. Puede intentar configurar su editor de modo que el editor espera un archivo para estar en UTF-8 (si usa un IDE real como NetBeans, entonces esto puede incluso convertirse en una configuración de proyecto que puede transferir junto con el código).

Una alternativa es probar algunos trucos: algunos editores intentan determinar la codificación usando algunas heurísticas basadas en el texto ingresado. Podría intentar comenzar cada archivo con

<?php //Úτƒ-8 encoded

y tal vez la heurística lo consiga. Probablemente haya mejores cosas para poner allí, y puede buscar en Google qué tipo de heurística de detección de codificación son comunes, o simplemente probar algunas 🙂

En general, recomiendo simplemente arreglar la configuración del editor.

Oh, espera, leí mal la última parte: para difundir el código a cualquier lugar, supongo que lo más seguro es hacer que todos los archivos solo contengan los caracteres inferiores de 7 bits, es decir, ASCII simple, o simplemente aceptar que algunas personas con editores antiguos ven tu nombre escrito divertido. No hay manera a prueba de fallas. La lista de materiales es definitivamente mala debido a los encabezados ya enviados. Por otro lado, siempre que solo coloque caracteres UTF-8 en los comentarios, el único impacto de que algún editor malinterprete la codificación son los caracteres extraños. Preferiría escribir correctamente su nombre y agregar un comentario dirigido a la heurística para que la mayoría de los editores lo entiendan, pero siempre habrá personas que verán caracteres falsos.

  • Gracias por los consejos. Entendí cuál es mi posición y creo que en lugar de la heurística de detección de codificación, que es un compromiso un poco extraño, haré la elección decente y simplemente deletrearé mi nombre con una “s” en lugar de una “ș”, la mayoría de las veces posibles. los codificadores ni siquiera tienen ese carácter en su idioma de todos modos. ¿Derecha? 🙂

    – treznik

    1 de abril de 2010 a las 14:39

  • Los navegadores no ignoran la lista de materiales. Y estos errores son difíciles de rastrear. Nunca guarde archivos PHP con BOM.

    – hakré

    9 de agosto de 2011 a las 11:52

  • No, porque no es un error. El BOM es una abominación, no lo uses.

    – Skrebel

    20 de marzo de 2018 a las 10:53

  • Lo más seguro es que sea un error. PHP podría “refluir” fácilmente al final de la fase de encabezado. Hay muchas buenas razones para las listas de materiales, incluido el hecho de que, a pesar de tener los medios técnicos para almacenar codificaciones de contenido fuera de banda junto con sus archivos (incluido xattr/windows ADS), nada realmente lo hace, así que… -Métodos de banda, como listas de materiales y la VERDADERA abominación de . Además, es solo un número mágico, como muchas codificaciones/formatos de archivo anteriores.

    – DimeCadmio

    18 de junio de 2018 a las 23:04


BOM causaría Headers already sent error, por lo tanto, no puede usar BOM en archivos PHP

1646753653 783 Firma UTF 8 BOM en archivos PHP
omabena

Esta es una publicación anterior y ya ha sido respondida, pero puedo dejarles algunos otros recursos que encontré cuando enfrenté este problema de BOM.

http://people.w3.org/rishida/utils/bomtester/index.php con esta página puede verificar si un archivo específico contiene BOM.

También hay un script útil que genera todos los archivos con BOM en su directorio actual.

<?php 
function fopen_utf8 ($filename) { 
    $file = @fopen($filename, "r"); 
    $bom = fread($file, 3); 
    if ($bom != b"\xEF\xBB\xBF") 
    { 
        return false; 
    } 
    else 
    { 
        return true; 
    } 
} 

function file_array($path, $exclude = ".|..|design", $recursive = true) { 
    $path = rtrim($path, "https://stackoverflow.com/") . "https://stackoverflow.com/"; 
    $folder_handle = opendir($path); 
    $exclude_array = explode("|", $exclude); 
    $result = array(); 
    while(false !== ($filename = readdir($folder_handle))) { 
        if(!in_array(strtolower($filename), $exclude_array)) { 
            if(is_dir($path . $filename . "https://stackoverflow.com/")) { 
                                // Need to include full "path" or it's an infinite loop 
                if($recursive) $result[] = file_array($path . $filename . "https://stackoverflow.com/", $exclude, true); 
            } else { 
                if ( fopen_utf8($path . $filename) ) 
                { 
                    //$result[] = $filename; 
                    echo ($path . $filename . "<br>"); 
                } 
            } 
        } 
    } 
    return $result; 
} 

$files = file_array("."); 
?>

Encontré ese código en php.net

Dreamweaver también ayuda con esto, le da la opción de guardar el archivo y no incluir las cosas de la lista de materiales.

Es una respuesta tardía, pero todavía espero que ayude. Adiós

  • El script fopen_utf8() me ayudó a aislar un archivo BOM de un SDK que estaba usando de un proveedor. ¡Muy útil!

    – Chris Rasco

    27 de enero de 2014 a las 18:10

Para que lo sepas, hay una opción en php, zend.multibyteque permite que php lea archivos con BOM sin dar la Headers already sent error.

Desde el archivo php.ini:

; If enabled, scripts may be written in encodings that are incompatible with
; the scanner.  CP936, Big5, CP949 and Shift_JIS are the examples of such
; encodings.  To use this feature, mbstring extension must be enabled.
; Default: Off
;zend.multibyte = Off

Firma UTF 8 BOM en archivos PHP
matthewv789

En PHP, además del error de “encabezados ya enviados”, la presencia de una lista de materiales también puede estropear el HTML en el navegador de formas más sutiles.

Ver Problemas de visualización causados ​​por la lista de materiales UTF-8 para obtener un resumen del problema con cierto enfoque en PHP (Internacionalización W3C).

Cuando esto ocurre, no solo suele haber un espacio notable en la parte superior de la página renderizada, sino que si inspecciona el HTML en Firefox o Chrome, puede notar que la sección del encabezado está vacía y sus elementos parecen estar en el cuerpo.

Por supuesto, ver la fuente mostrará todo donde se insertó, pero el navegador lo interpreta como contenido del cuerpo (texto) y lo inserta allí en el Modelo de objetos del documento (DOM).

1646753654 403 Firma UTF 8 BOM en archivos PHP
bobflux

O puede activar el almacenamiento en búfer de salida en php.ini, lo que resolverá el problema de los “encabezados ya enviados”. También es muy importante usar el almacenamiento en búfer de salida para el rendimiento si su sitio tiene una carga significativa.

1646753655 265 Firma UTF 8 BOM en archivos PHP
hakré

BOM es en realidad la forma más eficiente de identificar un archivo UTF-8, y tanto los navegadores modernos como los estándares admiten y fomentan su uso en cuerpos de respuesta HTTP.

En el caso de los archivos PHP, no es el archivo sino la salida generada la que se envía como respuesta, por lo que obviamente no es una buena idea guardar todos los archivos PHP con la lista de materiales al principio, pero eso no significa que no debas usar la lista de materiales. en tu respuesta

De hecho, puede inyectar de forma segura el siguiente código justo antes de su declaración de tipo de documento (en caso de que esté generando HTML como respuesta):

<?="\u{FEFF}"?> (o antes de PHP 7.0.0: <?="\xEF\xBB\xBF"?>)

Para leer más: https://www.w3.org/International/questions/qa-byte-order-mark#transcoding

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad