서버를 새로 만들면서 PHP 판을 5.4 로 올렸다. 사이트는 떴는데 검색이 이상하게 동작했다. 따옴표가 든 검색어를 넣으면 결과가 안 나왔다.
Table of contents
Open Table of contents
옛 판이 가려 주고 있었다
찾아보니 magic_quotes_gpc 였다. $_GET 과 $_POST 로 들어온 값에 addslashes 를 자동으로 걸어 주던 설정이다. PHP 5.4 에서 이 지시어가 제거됐고 코드는 그것에 기대고 있었다. 이스케이프를 안 하니 쿼리에서 문자열이 깨졌다.
원래는 코드가 mysql_real_escape_string 으로 직접 처리했어야 하는 것이었다. 옛 판이 대신 해 주면서 문제가 가려져 있었다. 판올림이 새 문제를 만든 것이 아니라 있던 문제를 드러낸 것이었다.
조용한 쪽이 더 어려웠다
같은 이유로 다른 것도 찾아봤다. PHP 5.4 는 safe_mode 와 register_long_arrays 와 allow_call_time_pass_reference 도 함께 없앴다. 없어진 함수를 쓰는 자리는 Fatal error 가 나서 바로 드러났다. 문제는 오류 없이 다르게 동작하는 쪽이었다.
register_globals 가 사라진 자리가 그랬다. $_GET['mode'] 가 $mode 로 자동으로 들어오던 것이 이제 안 들어온다. 그 변수가 항상 비어 있게 되니 조건이 언제나 거짓이 됐다. 화면은 정상으로 뜨고 결과만 틀렸다.
오류를 다 보이게 하고 훑었다
확인용 환경에서 error_reporting(E_ALL) 과 display_errors = On 을 걸었다. 5.4 부터 E_ALL 에 E_STRICT 가 포함돼서 따로 붙일 필요가 없어졌다. 평소에 꺼 두는 E_NOTICE 가 단서가 됐다. Undefined variable 알림이 그 자리를 그대로 가리켰다.
화면을 하나씩 열면서 나오는 알림을 log_errors 와 error_log 로 파일에 받았다. 그런 다음 알림 종류별로 묶어 세었다. 같은 원인이 여러 화면에서 나오니 묶어 놓으면 고칠 순서가 정해졌다.
목록으로 지워 나간 자리
고칠 자리를 목록으로 만들고 하나씩 지웠다. 목록이 없으면 몇 개를 고쳤는지 기억에 의존한다. 실제로 처음에는 다 고쳤다고 생각했는데 목록에 절반이 남아 있었다.
전부 지운 뒤에 다시 훑어서 새로 나오는 알림이 없는지 봤다. 판올림 전에 이 작업을 했으면 훨씬 쉬웠을 것이다. 5.3 에서도 E_DEPRECATED 를 켜 두면 없어질 기능에 기댄 자리가 미리 보인다.
정리
- 판올림에서 안 되는 것이 원래 문제일 수 있다
- PHP 5.4 는
magic_quotes_gpc와register_globals를 제거했다 safe_mode와register_long_arrays도 같이 없앴다addslashes를 대신 해 주던 것이 사라지면 쿼리가 깨진다- 함수 제거는
Fatal error가 나서 찾기 쉽다 - 설정 제거는 조용히 결과만 바꾼다
error_reporting(E_ALL)로E_NOTICE까지 켠다- 5.4 부터
E_ALL에E_STRICT가 들어 있다 error_log로 받아 종류별로 묶는다- 고칠 자리를 목록으로 만들고 하나씩 지운다