Настроение сейчас - Отличное!
Приветствую вас дорогие читатели! [показать]
Помните, я писал уже раньше историю о трех лишних байтах и генерации динамических картинок в Zend Framework?
Так вот, тогда эти три злополучных байта изрядно поморочили головы, как мне, так и моему коллеге. Но решив какую-то проблему сразу о ней забываешь, откладывая разве что куда-то на пыльную полку с подписью "Одноразовый опыт". А зря! Ведь покопайся я тогда глубже в проблеме, то понял бы, что дело было вовсе не в лишних строках, а все таки в лишних трех байтах :)
Постановка задачи:
Создать простую web страничку, используя в качестве шаблонизатора Smarty. Страница должна представлять собой валидный HTML документ состоящий из трех классических, я бы сказал, блоков: шапки, контента, подвала. Блоками, как водиться, у нас будут <div>. А центральный блок, который будет наполняться контентом должен подключаться, как include_file в главном Smarty шаблоне. Сказано - сделано. Ничего сложного, правда? Я тоже так думал и потому быстро набросал верстку страницы на всякий случай опробовав ее в Опере, Firefox, Explorer 6.
Суть проблемы:
Но, представьте моё удивление, когда я обнаружил странную солидарность FF и IE! Оказалось что Опера выдает все ровно в том виде, как и стоило ожидать - блок шапки, блок контента ( из отдельного шаблона ) и блок подвала с копирайтами.
Вышеупомянутые же товарищи (не замечал раньше за ними такой сплоченности) не захотели следовать задумке автора и выдавали несколько иную картинку: блок шапки, пропуск в одну строку и собственно после этого пропуска блок контента естественно с нижеследующим подвалом.
Так сформулировалась суть проблемы: убрать любой ценой лишний промежуток. [показать]
Попытки решения: (Внимание - много воды! Можете смело пропускать)
Стоит сказать, что я умолчал об одном элементе страницы, который замедлил процесс поиска решения. Этим элементом была горизонтальная линия <hr />, которая должна была визуально отделять шапку, от тела страницы. Конечно все подозрения пали в первую очередь на этот элемент, так как о его сложном поведении при стилизации в различных браузерах известно и написано много.
Не найдя управы на несчастный <hr />, я решил перестать изображать из себя дизайнера и обратиться к опытной знакомой. Она воссоздала, как сказала сама, место преступления, применила кое-какие хитрости к горизонтальной линии и в итоге не получила каких либо проблем.
Я остался опять наедине со странным глюком двух таких разных браузеров, гадая, что же могло послужить причиной их ненормального поведения.
Конечно я заглядывал сто раз в код страницы в Опере и в остальных браузерах, но ни в одной буковке разницы не было, а потому я поступил более радикально - убрал горизонтальную линию. Проблема, как не сложно догадаться, осталась на месте и промежуток зиял уже не между <hr /> и <div>, а прямо между блоками.
Следующим в моём мыслительном процессе числился вполне логичный прием - перенести содержимое подключаемого шаблона прямо в основной шаблон. Хотя по задумке проекта так быть не должно, я надеялся, что это подтолкнет меня к разгадке. Так оно и получилось. [показать]
Решение задачи:
Дальше - проще. Зная, что инклуд влияет на эту пустую строку, я пошел копать в направлении самого Smarty. И хотя шаблонизатор не зависит от браузера, как и браузер не зависит от шаблонов сервера (на столько что бы по разному работать в разных браузерах), ничего более логичного, чем допустить косвенную связь, мне не оставалось.
Я еще раз потыкался по файлам главного и подключаемого шаблонов, даже попробовал написать их в одну строку а когда эти меры не помогли, пошел глядеть, что там у нас находится в откомпилированном кеше шаблонизатора (по умолчанию папка templates_c). Просмотр главного шаблона ничего не дал, а вот при чтении кода подключаемого блока, я встретил там странный символ перед самым div'ом, похожий на точку написанную в верхнем индексе.
Быстро скачав классный HEX редактор я открыл в нем злосчастный файл и увидел что наша странная точка это вовсе не точка, а целых три (догадываетесь каких?) байта, известных в разных кругах, как:
v или п»ï или EF BB BF или 239 187 191 или
0xFEFF или 65279 или BOM или яЛП
Этот коварный знак забирает так много времени и усилий программистов, но его так сложно обнаружить, если о нем просто не знать заранее! Не потому ли эти три байта на столько неуловимы, что имеют так много разных обликов и имен?
Самое известное из имен - byte-order mark (BOM). Самая распространенная проблема, на сколько мне известно: яЛП.
Злостный враг всех программистов и, как выяснилось, даже верстальщиков и дизайнеров - признак кодировки файла при использовании UTF-8. И, как видите, одно из его проявлений - лишний пропуск между двумя блоками. Разработчикам Opera +1 за то, что приучили свой браузер самостоятельно справляться с этой проблемой. А что бы угодить всем остальным, не остается ничего другого, как в том же HEX эдиторе удалить три байта с кодами EF BB BF в начале подключаемого шаблона.
Заходим в браузер, нажимаем F5 и... Все встает на свои места, где ему и положено быть, а лично я получаю еще один опыт, уже точно зная на следующий раз с каким зверем придётся иметь дело и как вести себя, что бы уже не пришлось "лететь под радаором", как я поступил с Zend и картинками в прошлый раз.
Если и вам помогло - рад был подсказать [показать]
UPD: Кроме того дополнительные советы можно посмотреть тут: http://smileart.habrahabr.ru/blog/52437/#comments В чвстности по скольку проблема была через Zend For Eclipse, мне помогло ручное включение UTF-8 еще и в настройках самого проекта, кроме настроек IDE!
( Сперто с: http://garfield.vexer.ru/post91370071/)