PHP: как удалить BOM в WordPress
Одна из проблем использования кодировки UTF-8 — метка BOM. Эта метка нужна для отделения UTF от др. кодировок, но в случае с UTF-8 это может привести к ряду проблем, поэтому лучше отказаться от кода BOM. Как это сделать?
Удалить BOM в Notepad++
Самый простой вариант – преобразовать кодировку документа. Советую использовать для этого бесплатный текстовый редактор Notepad++, который умеет нормально работать с кодировками: ANSII, UTF-8, UTF-8 (без BOM) и др.
- Скачайте и установите последнюю версию Notepad++ с оф. сайта notepad-plus-plus.org
- Откройте документ в текстовом редакторе и кликните пункт в меню «Кодировка».
- Здесь есть как выбор отображения, так и само преобразование (отдельно).
Удалить BOM средствами PHP
Когда файлов много, перелопачивать их в Notepad++ долго. Проще воспользоваться php-скриптом рекурсивной обработки папок и файлов для удаления метки BOM. Его я разделил на три функции:
1. Функция file_has_boom($filename)
— проверяет наличие метки BOM в файле $filename
.
function file_has_bom($filename) {
$fh = fopen($filename, 'r');
if ( $fh === false ) return false;
$str = fread($fh, 3);
fclose($fh);
return ( $str == pack('CCC', 0xef, 0xbb, 0xbf) );
}
Она читает первые 3 байта из файла $filename
и сравнивает их со значением метки BOM. Если такая есть – возвращает TRUE
, иначе – FALSE
.
2. Функция file_remove_bom($filename)
— удаляет первые 3 байта (под метку BOM) в файле.
function file_remove_bom($filename) {
$str = file_get_contents($filename);
if ( $str === false ) return false;
$str = substr($str, 3);
return file_put_contents($filename, $str);
}
Если открыть или перезаписать файл не удалось, функция вернёт FALSE
, иначе &mdah; количество записанных байтов (не TRUE).
3. Функция dir_remove_bom($dir)
— делает рекурсивную обработку папок и файлов, проверку файлов на наличие метки BOM и её удаление из них.
function dir_remove_bom($dir) {
$dh = opendir($dir);
if ( $dh === false ) die($dir .' - <font color="#ff0000">ERROR DIR</font>');
while ( ( $file = readdir($dh) ) !== false ) {
if ( $file == '.' or $file == '..' ) continue;
$filename = $dir .'/'. $file;
if ( is_dir($filename) ) {
dir_remove_bom($filename);
} elseif ( is_file($filename) ) {
if ( file_has_bom($filename) !== false ) {
echo $filename .' - '. ( ( file_remove_bom($filename) !== false ) ? '<font color="#008000">REMOVE BOM</font>' : '<font color="#ff0000">ERROR FILE</font>' ) . '<br>';
}
}
}
closedir($dh);
}
Примечание: функция выводит список файлов, в которых имелась метка BOM и результат попытки её удаления.
Здесь можно было бы использовать и функцию glob()
, но о ней я узнал только когда начал разбираться с тем, как удалить файл в php – увы мне.
Удаление BOM из файлов WordPress
При чём тут WordPress? Дело в том, что WordPress использует кодировку UTF-8, и предложенный php-скрипт писался именно для него.
В сети Интернет есть решение от Юрия Белотицкого, но оно лишь находит проблемные файлы и не удаляет метку BOM (это нужно делать вручную, используя тот же Notepad++).
Из плюсов стоит отметить ограничение — фильтр обрабатываются только .php файлы, это правильно и ускоряет процесс. В моём решении этого нет, но добавить не сложно:
if ( strstr($filename, '.php') === false ) continue;
Добавьте этот код перед проверкой наличия в файле метки BOM, т. е. строки:
if ( file_has_bom($filename) !== false ) {
Ну а т.–к. основная часть проблем связана именно с шаблонами, то достаточно проверить папку ./wp-content/themes/ – при этом php-скрипт должен находиться в корневой папке блога и вызов обработки будет иметь вид:
dir_remove_bom('./wp-content/themes/');
К тому же можно указать папку самой темы, что еще сузит круг обрабатываемых файлов.
BOM и итоги
Вариантов решения проблемы много. Будущее за UTF-кодировками! Но пока есть сложности с UTF, стоит признать, что кодировка Windows-1251 (ANSI) выглядит куда как предпочтительней.
P.S. я не несу ответственности за последствия использование приведенного php-скрипта по удалению BOM.
Короткая ссылка: http://goo.gl/ZPXH8r
Спасибо, хотя как перешел на PhpStorm уже забыл, что такое BOM. Да и что такое opendir уже забыл после появления в PHP SPL и файловых итераторов.
PhpStorm платный. К слову, я не совсем понял, какое отношение редактор имеет к проблеме метки BOM при использовании кодировки UTF-8. Вы хотите сказать, что PhpStorm недоредактор, который не осиливает использования BOM? Эта метка, на самом деле нужна, но она более актуальна для UTF-16, UTF-32 и иже. Опять же, при заливке файлов на хостинг может случится разное и PhpStorm тут вряд ли поможет, но утверждать что-то не возьмусь.
Насчет PHP SPL, не думаю, что яйца в профиль смотрятся как-то иначе. Я использую то, что мне привычней, но согласен - надо не отставать от новшеств... если есть такое желание :-)