Diventa un rompicapo, se si ha il BOM UTF8 all’inizio del file PHP, XML o javascript. Questi files devono inviare la loro intestazione prima di ogni altra cosa. A causa della posizione del BOM, che sono i primi bytes del file, le intestazioni non possono essere ricevuti dai browsers e potrebbero verificarsi errori non intenzionali.
Il Byte Order Mark (BOM) è un carattere Unicode che viene utilizzato per indicare l’ordine dei byte (endianness) di ogni parola di 4 byte in un file di testo. Il codice è U + FEFF. Oltre ad essere usato per indicare l’ordine dei byte in ogni parola può anche essere utilizzato come marchio per indicare la codifica Unicode (UTF-8, UTF-16 o UTF-32) che si sta utilizzando.

Verificare il BOM con PHP
Con PHP, quando si presenta il problema, l’errore visualizzato sarà “Attenzione: Impossibile modificare le informazioni di intestazione” o in inglese “Warning: Cannot modify header information“, e con XML, “XML dichiarazione consentito solo all’inizio del documento” o in inglese “XML declaration allowed only at the start of the document“. Se si riscontrano errori di intestazione di questo tipo nel vostro blog, è molto probabile che sia causato da un byte order mark nel file del theme (controllare prima il file functions.php del vostro theme).
Come si può trovare ed eliminare questi BOM dal file di testo? La maggior parte dei frameworks e editor includono un’impostazione per il salvataggio dei file non BOM UTF8. Controlla il file di aiuto, o chiedere al helpdesk o in qualche forum quale strumento si sta’ utilizzando. In secondo luogo, non usare mai Notepad su Windows per scopi di sviluppo. perché inserisce direttamente il BOM quando si salva il file in formato UTF8.
Se avete a che fare con una centinaia di files, trovare ed eliminare il BOM è un’avventura in termini di tempo. Bisognerebbe creare uno script che legge il file, o magari l’intera cartella e sottocartelle, per individuare se questa serie di caratteri ci sono per elencarli a fine processo. Se la lista non è abbbastanza lunga possiamo aprire il nostro file elencato con l’editor adatto per rimuovere i primi tre strani caratteri che si trovano all’inizio del file.
Ci serviremo quindi di una funzione che legge il contenuto del file recursivamente e un’altra funzione che setaccia il contenuto, ritornando un booleano per popolare un array che sarà utilizzato per visualizzare l’elenco di files individualti.
Prima di eseguire la verifica controllare la linea dove è definita la variabile $PERCORSO, e cambiarla con la vostra home directory. Potete anche provare a impostarla su DOCUMENT_ROOT o sul percorso del file. Se i files sono ospitati su una macchina basata su OS Windows, non dimenticare di modificare il valore della variabile $osWIN a 1, e usare un insieme diverso di barre (slashes): le rovesciate doppie.
<?php 
// Indicare il percorso della cartella principale.
// Si può  provare questa
// $PERCORSO = $_SERVER["DOCUMENT_ROOT"];
// o questa
// dirname(__FILE__)
$PERCORSO = dirname(__FILE__);
// Si tratta di un host Windows? 
// s'è  così , cambiare questa linea a $osWIN = 1;
$osWIN = 0;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Elenca il BOM UTF8</title>
    <style>
      body { font-size: 10px; font-family: Arial, Helvetica, sans-serif; background: #FFF; color: #000; }
      .trovato { color: #F30; font-size: 14px; font-weight: bold; }
    </style>
  </head>
  <body>
<?php
$arBOM = array();
CartellaRicorsiva($PERCORSO);
echo '<h2>Questi files hanno il BOM UTF8:</h2><p class="trovato">';
foreach ($arBOM as $utf) { echo $utf ."<br />\n"; }
echo '';
// finder ricorsivo
function CartellaRicorsiva($argPERCORSO) {
  global $arBOM, $osWIN;  
  $win32 = ($osWIN == 1) ? "\\" : "/";  
  $cartella = dir($argPERCORSO);  
  $cartelle_trovate = array();
  while ($file = $cartella->read()) {
    if($file != "." and $file != "..") {
      if(filetype($argPERCORSO . $win32 . $file) == "dir"){
        $cartelle_trovate[count($cartelle_trovate)] = $argPERCORSO . $win32 . $file;
      } else {
        $bBOM = CercaBOM(file_get_contents($argPERCORSO . $win32 . $file));
        if ($bBOM) $arBOM[count($arBOM)] = $argPERCORSO . $win32 . $file;
      }
    }
  }
  $cartella->close();
  
  if(count($cartelle_trovate) > 0) {
    foreach ($cartelle_trovate as $cartella) {
      CartellaRicorsiva($cartella, $win32);
    }
  }
}
// Cerca il BOM nei files
function CercaBOM($string) { 
    if(substr($string, 0,3) == pack("CCC",0xef,0xbb,0xbf)) return true;
    return false; 
}
?>
  </body>
</html>
Rimuovere il BOM con PHP
Alcune persone mi hanno chiesto s’è possibile rimuovere il BOM dai files con PHP senza danneggiarlo; e se PHP può fare questo. Avevano centinaia di files con il BOM UTF8 e ci sarebbe voluto troppo tempo per rimuoverli a mano, se non erano in grado di trovare una soluzione.
La mia risposta fu, “certamente”. PHP in grado di leggere e rimuovere il BOM da ogni file. Siccome ho trovato questo problema solo sui file di testo, un rimuovitore di caratteri sulla stringa farà il compito usando la funione nativa di PHP chiamando substr().
Alla fine del post, potete trovare lo stesso codice php di prima per verificare il BOM, ottimizzato per rimuovere l’UTF8 BOM dai nostri progetti.
Ricordare
Fare un backup completo dei files prima di eseguire questo script. Alcuni files e softwares dipendono dal BOM per capire la codifica del suo contenuto. Non accetto alcuna responsabilità su come è stato utilizzato il codice o quello che è successo con esso. Quindi, stai attento.
Dopo questo parragrafo paranoico, ecco il codice ristrutturato. È sufficiente copiare incollare un file di testo, salvarlo con l’estensione php ed eseguirlo dal browser. Usate, se volete, il notepad, questo codice rimuoverà anche il BOM da se stesso.
<?php 
// Indicare il percorso della cartella principale.
// Si può  provare questa
// $PERCORSO = $_SERVER["DOCUMENT_ROOT"];
// o questa
// dirname(__FILE__)
$PERCORSO = dirname(__FILE__);
// Si tratta di un host Windows? 
// s'è  così , cambiare questa linea a $osWIN = 1;
$osWIN = 0;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Cerca e Rimuove il BOM UTF8</title>
    <style>
      body { font-size: 10px; font-family: Arial, Helvetica, sans-serif; background: #FFF; color: #000; }
      .trovato { color: #F30; font-size: 14px; font-weight: bold; }
    </style>
  </head>
  <body>
<?php
$arBOM = array();
CartellaRicorsiva($PERCORSO);
echo '<h2>Questi file hanno BOM UTF8 e sono stati puliti:</h2><p class="trovato">';
foreach ($arBOM as $utf) { echo $utf ."<br />\n"; }
echo '';
// finder ricorsivo
function CartellaRicorsiva($argPERCORSO) {
  global $arBOM, $osWIN;  
  $win32 = ($osWIN == 1) ? "\\" : "/";  
  $cartella = dir($argPERCORSO);  
  $cartelle_trovate = array();
  while ($file = $cartella->read()) {
    if($file != "." and $file != "..") {
      if(filetype($argPERCORSO . $win32 . $file) == "dir"){
        $cartelle_trovate[count($cartelle_trovate)] = $argPERCORSO . $win32 . $file;
      } else {
        $contenuto = file_get_contents($argPERCORSO . $win32 . $file);
        $bBOM = CercaBOM($contenuto);
        if ($bBOM) {
          $arBOM[count($arBOM)] = $argPERCORSO . $win32 . $file;
          
          // Rimuove i primi tre caratteri dal file
          $contenuto = substr($contenuto,3);
          // Scrive di nuovo il file pulito
          file_put_contents($argPERCORSO . $win32 . $file, $contenuto);
        }
      }
    }
  }
  $cartella->close();
  
  if(count($cartelle_trovate) > 0) {
    foreach ($cartelle_trovate as $cartella) {
      CartellaRicorsiva($cartella, $win32);
    }
  }
}
// Searching for BOM in files
function CercaBOM($string) { 
    if(substr($string,0,3) == pack("CCC",0xef,0xbb,0xbf)) return true;
    return false; 
}
?>
</body>
</html>
Rimuovere il BOM con Perl
In alternativa si può creare un file in Perl e lanciarlo dalla riga di comando. Indicare il file da analizzare, come argomento, prima dell’invio. Questo leggerà un file dallo stdin e rimuoverà, se è presente, il BOM all’inizio della prima linea per stamparlo nello stdout.
#!/usr/bin/perl
@file=;
$file[0] =~ s/^\xEF\xBB\xBF//;
print(@file);
Similari
Restrizioni per caricare un file con PHP
13% Php
Dalle foto di famiglia ai documenti aziendali, file uploads potenzia molte delle applicazioni web più importanti. [expand title=”L’oggetto $_FILES” startwrap=”” endwrap=”” excerpt=”⤽” swapexcerpt=”” expanded=”true” trigcla…
Caricare i files con jQuery
10% JQuery
jQuery File Upload è un widget di jQuery per tutti i tipi di progetti web che vogliono offrire la possibilità di caricare dei files nel proprio sito. Questo widget fornisce un interessante supporto per caricare i files in …
Marcatura HTML5
7% Html5
Anche se molte persone non hanno mai sentito parlare, l’XHTML è davvero il futuro di Internet. È l’ultima generazione di HTML, venuta dopo la versione 4, che ha molte nuove caratteristiche che lo avvicinano, in qualche mod…
redirect 301 usando mod_alias
7% Server
mod_alias è fondamentalmente la versione più semplice di mod_rewrite. Non può fare le cose che fa mod_rewrite, ad esempio modificare la stringa di query. Per eseguire reindirizzamenti nel server web Apache è possibile di u…
Installare Python e Django su Windows
7% Django
Quando ci riferiamo allo sviluppo web con Python, la prima cosa che viene in mente è usare un qualche framework. Il più famoso e utilizzato da tutti è il Django, ma non è l’unico. Ci sono Pylons, Grok, TurboGears e Zope: t…