Bonjour à tous,

Je sais que le sujet des BOM a déjà été traité des bazillions de fois sur ce forum comme sur d'autres, et qu'en général les problèmes d'encodages peuvent être résolus en utilisant de l'UTF-8 sans BOM, mais je pose quand même la question :

Y a-t-il un moyen pour que PHP en tant que module Apache gère les BOM ?

Je pose la question car j'ai récemment fait un site utilisant du PHP, où une partie des fichiers est en UTF-8 *avec* BOM et que ça n'a pas semblé poser de problème jusqu'à présent... Sauf que je viens de faire un checkout de mes sources sur mon nouveau macbook, et que j'ai de magnifiques losanges/points d'interrogations en guise de caractères accentués.

Sur mes deux autres postes de dév (windows et ubuntu, également apache/php), je n'avais pas ce genre de problèmes, bien que les fichiers en question commençaient également par une BOM ! De même sur le serveur de prod tournant sous linux (un mutu OVH).

Par contre en virant les BOM je n'ai plus le souci sur mon mac... Pourquoi-t-est-ce que ça marchons pas partout pareil ?!
Nebelmann a écrit :
Y a-t-il un moyen pour que PHP en tant que module Apache gère les BOM ?

PHP n'a pas besoin de gérer les BOM d'une quelconque manière.
Les byte-order marks sont des séquences d'octets (trois il me semble) en tout début de fichier qui indiquent l'ordre des octets dans le fichier. Ils sont utiles en UTF-16 qui peut être encodé de deux manières différentes (little endian, big endian). En UTF-8, il n'y a qu'un seul ordre possible pour les octets qui codent un même caractère, donc la seule utilité du BOM est de faciliter la détection du codage (un fichier qui commence par un BOM UTF-8 est un fichier UTF-8).

Il est tout à fait possible d'encoder des fichiers destinés à un site web en UTF-8 avec BOM. Par contre, quand le navigateur reçoit un fichier encodé en UTF-8 (fichier texte brut, CSS, JavaScript, XML, page HTML...) ce fichier doit soit:
- ne pas avoir de BOM;
- avoir un seul BOM, en tout début de fichier (trois premiers octets).

Le problème arrive quand tu fais ceci:
Voici un fichier PHP qui génère un contenu...
<?php include('un_fichier_en_utf8_avec_bom.php'); ?>
Etc.

Si tu fais ça, tu te retrouves avec un BOM en plein milieu du contenu. Et si les trois octets du BOM ne sont pas tout au début du fichier, ce n'est plus un BOM mais une simple séquence d'octets que le navigateur (ou tout autre logiciel qui lit ce fichier) va chercher à afficher (ce qui donne en général .

Donc les fichiers que tu inclus ne doivent pas être en UTF-8 avec BOM. Ou bien la fonction utilisée pour les inclure doit supprimer le BOM à la volée, pourquoi pas.

Nebelmann a écrit :
Sauf que je viens de faire un checkout de mes sources sur mon nouveau macbook, et que j'ai de magnifiques losanges/points d'interrogations en guise de caractères accentués.

Bah c'est juste que tu as des données en ISO-8859-1 (ou éventuellement Windows-1252 ou MacRoman ou autre) que tu essaies d'afficher en UTF-8. Je vois pas le rapport avec la présence ou non d'un BOM parasite dans tes pages.
fvsch a écrit :
Bah c'est juste que tu as des données en ISO-8859-1 (ou éventuellement Windows-1252 ou MacRoman ou autre) que tu essaies d'afficher en UTF-8. Je vois pas le rapport avec la présence ou non d'un BOM parasite dans tes pages.


C'est bien là mon problème, tous mes fichiers sont bien en UTF-8 et reconnus comme tels dans Notepad++ ou Coda... Des fichiers avec BOM qui incluent un header sans BOM :

<? // définition de variables...;
include(header.php); // sans BOM


Et avec exactement les mêmes fichiers, je n'ai pas le problème sous linux ni sous windows. Sur mon mac apache a un AddDefaultCharset utf-8, et dans la réponse j'ai bien un content-type en UTF-8. Toute la chaine semble donc utiliser de l'UTF-8 de bout en bout, sauf qu'en fait non et je ne trouve pas d'où ça vient.

En copiant collant un fichier PHP dans un nouveau fichier que j'enregistre avec Coda, cette fois je n'ai plus de BOM et la page s'affiche correctement dans le navigateur. Je précise aussi que les 3 fameux premiers caractères EF BB BF ne sont pas affichés dans la réponse du serveur.
Modifié par Nebelmann (05 Mar 2011 - 19:23)
Et quand ça s'affiche mal, le navigateur utilise quel codage pour afficher la page? (Même question dans le cas où ça s'affiche bien.)
Si tu fais un wget (ou curl) de la page pour en récupérer une copie statique, qu'est-ce que ça donne? Au besoin, vérifier les octets exacts avec un éditeur hexadécimal (Hex Fiend par exemple).
Le navigateur semble toujours utiliser UTF-8, encodage spécifié dans mes balises meta.
A coup de telnet, j'avais remarqué que le serveur renvoyait un content-type UTF-8 mais que les accents étaient bien remplacés par des "?". Mon shell est configuré également en UTF-8, ça ne semble pas être un problème au niveau du navigateur, mais bien de l'encodage dans lequel PHP ouvre ou rend mon fichier .php...

Un hexdump me dit que le fichier inclu est sans BOM, le fichier qui inclut avec BOM.