[Coding Standard(PSR-1)] PHP code MUST use only UTF-8 without BOM.
PSR-1: Basic Coding Standard - PHP-FIG
PHP의 규약인 PSR-1:Basic Coding Standard에는 문자 인코딩에 대해서 규약을 정하고 있다.
웹환경에서는 UTF-8을 비롯해서 UTF-16, UTF-32 등 다양한 인코딩 방식을 씁니다.
이렇게 비슷한 방식을 사용하는 문서는 Byte Order Mark(BOM)로 구별이 됩니다.
하지만 이것은 문제를 일으킬 수 있습니다.
BOM은 인코딩된 문서 첫 머리에 사용되어 정확한 인코딩 방식을 알려주는 역할을 하는데 대표적인 인코딩 방식과 그에 따른 BOM 목록은 아래 표와 같습니다.
인코딩 방식 | Byte Order Mark(BOM) |
UTF-8 | EF BB BF |
UTF-16 Big Endian | FE FF |
UTF-16 Big Endian | FE FE |
UTF-32 Big Endian | 00 00 FE FF |
UTF-32 Big Endian | FF FE 00 00 |
UTF-8은 다른 인코딩 방식과는 다르게 BOM의 순서가 EF BB BF로 정해져 있습니다. 그래서 이 BOM은 바이트 순서와(Byte Order) 상관없기 때문에 UTF-8 Signature라고 불리지요. 즉, 해당 문서가 UTF-8로 인코딩되었다는 사실을 알리는 사인(signature)입니다.
문제
UTF-8은 인코딩 형식이 고정되어 있기 때문에 BOM이 없어도 인코딩 방식을 자동으로 알아낼 수 있습니다. 따라서 실제로는 BOM이 불필요하지요.
하지만 일부 윈도우즈 프로그램(메모장 같은)은 UTF-8 파일을 생성할 때 자동으로 BOM을 집어넣습니다. 윈도우즈 환경에서는 눈에 띄지 않는 경우가 많지만 리눅스(LINUX)나 유닉스(UNIX) 환경에서는 많은 문제를 일으키는 원인이 되지요.
대표적인 예로 PHP에서 include 구문을 사용할 때 생기는 여백(space)을 들 수 있습니다. 이것은 비단 BOM의 문제 뿐 아니라 웹 서버의 설정과도 관련이 있기 때문에 모든 경우에 생기는 문제는 아닙니다.
ex)IE에서 같은 소스여도 bom의 차이에 따라 다르게 보이는 문서 ,웹 서버 환경에 따라서도 동일한 문제 발생.
왜 같은 소스인데 다르게 보일까?
눈에 보이지 않는 BOM때문에 착각하기 쉽다.
같은 소스로 된 문서여도 이 2개의 인코딩 방식(with BOM, without BOM)은 완전히 동일하지 않습니다. 단지 이 차이가 일반적인 환경에서는 보이지 않을 뿐입니다. 하지만 인클루드 되는 파일을 헥사 에디터((hex editor)로 열어보면 아래 이미지처럼 차이가 드러납니다.
결론
BOM은 파일의 인코딩 방식을 쉽게 파악할 수 있다는 장점이 있지만, 물론 상황마다 다르긴 하겠지만, 유닉스 환경에서는 자제하는 게 좋을 것 같고, psr규칙에도 이런 것이 있으니, 사용하지 않는 것을 디폴트로 여겨야 할 것 같다.
참고
unicode - What's the difference between UTF-8 and UTF-8 with BOM? - Stack Overflow
The Unicode Standard, Version 5.0--electronic edition
wystan's tales > UTF-8 인코딩에서의 BOM(Byte Order Mark) 문제