프로그래밍 언어(must-have skills)/PHP

[Coding Standard(PSR-1)] PHP code MUST use only UTF-8 without BOM.

트밀 2023. 2. 11. 18:34

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)로 열어보면 아래 이미지처럼 차이가 드러납니다.

본인은 자주 쓰는 노트패드++에다가 hex 플러그인을 깔아서 확인해 보았다.
without bom

 

with bom

 

결론

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) 문제