PHP: как удалить BOM в WordPress

Одна из проблем использования кодировки UTF-8 — метка BOM. Эта метка нужна для отделения UTF от др. кодировок, но в случае с UTF-8 это может привести к ряду проблем, поэтому лучше отказаться от кода BOM. Как это сделать?

PHP: как удалить BOM в WordPress

Удалить BOM в Notepad++

Самый простой вариант – преобразовать кодировку документа. Советую использовать для этого бесплатный текстовый редактор Notepad++, который умеет нормально работать с кодировками: ANSII, UTF-8, UTF-8 (без BOM) и др.

  • Скачайте и установите последнюю версию Notepad++ с оф. сайта notepad-plus-plus.org
  • Откройте документ в текстовом редакторе и кликните пункт в меню «Кодировка».
  • Здесь есть как выбор отображения, так и само преобразование (отдельно).

преобразование кодировки файла в Notepad++ и удаление BOM

Удалить 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

alexander.plutov
alexander.plutov комментирует...

Спасибо, хотя как перешел на PhpStorm уже забыл, что такое BOM. Да и что такое opendir уже забыл после появления в PHP SPL и файловых итераторов.

Константин Кирилюк
Константин Кирилюк комментирует...

PhpStorm платный. К слову, я не совсем понял, какое отношение редактор имеет к проблеме метки BOM при использовании кодировки UTF-8. Вы хотите сказать, что PhpStorm недоредактор, который не осиливает использования BOM? Эта метка, на самом деле нужна, но она более актуальна для UTF-16, UTF-32 и иже. Опять же, при заливке файлов на хостинг может случится разное и PhpStorm тут вряд ли поможет, но утверждать что-то не возьмусь.

Насчет PHP SPL, не думаю, что яйца в профиль смотрятся как-то иначе. Я использую то, что мне привычней, но согласен - надо не отставать от новшеств... если есть такое желание :-)