마스터포유(Master4U)
Monday, 17 of January
 

로그인 Category
MySQL 4.1.x 와 character set
관리자  2009-08-22 02:10:54 Hit:2204
링크 #1: http://www.shimminkyu.com/tc/1016

MySQL 4.1.x 와 character set
어느 중소기업의 웹싸이트를 손봐주기로 했다.
따로 개발서버나 테스트 서버를 운영하고 있지 않았기 때문에
손을 보려면 먼저 개발 서버를 구축해야했다.
'하루면 되겠지...' 하고 생각했던 것이 벌써 며칠이 지나갔다.
문제는 다름아닌 character set 과 collation.

character set은 알파벳과 같은 특정 언어의 문자집합 그리고 collation은 그 문자집합의 구성요소들을 구분해주는 룰이라고 볼 수 있다. 자세한 내용은 위키피디어를 참조하고 한글을 사용하기 위한 character set은 주로 euc-kr, cp949, ISO-2022-KR utf8 등이 있다. 이걸 자세히 들여다보면 지옥인데... euc-kr 한가지만해도 어떤 어플리케이션은 euc-kr이라고 쓰는가하면 다른 녀석은 eucKR이라고 쓰기도 하고 euckr이라고 쓰는 녀석도 있다. 게다가 특정 데이터가 어떤 character set으로 이루어져있는가는 해당 charset으로 까보기전엔 모른다.

하여간 이게 어떤 문제를 야기했는가 하면
먼저 운영중인 웹싸이트의 웹서버는 Apache로 euc-kr로 운영중이고
DB서버는 MySQL 4.1.x로 역시 euckr로 운영중이었다.
여기까진 심플했다.

MySQL Administrator에서 DB 덤프를 뜨고 gFTP로 소스를 받아왔다.
SQL 덤프화일을 개발DB에 부어넣고 룰루랄라 웹페이지를 열었는데
오잉? 그리 낯설지만은 않은 물음표가 화면에 가득한거다.
바보 브라우저가 인코딩을 잘못 잡았나? 해서 요리죠리 바꿔봐도 글자는 꿈틀꿈틀거릴뿐 의미가 통하는 한글로 바뀌지는 않았다.

euc-kr로 출발해서 euc-kr로 읽었는데 인코딩이 깨진다라... 오 이런...
갑자기 머리속이 아득해졌다.
먼저, 소스화일들을 다운받은 gFTP는 어떤 인코딩을 쓸까.
DB를 백업받은 MySQL Admin은 또 어떤 인코딩을 쓰며
Apache2 웹서버는? 웹서버에 물려 돌아가는 PHP4는?
그리고 새 개발 MySQL DB는?
터미널인 Gnome Terminal은? 텍스트에디터인 Vim은?
거쳐온 모든 경로를 다 따져봐야한다 ㅡㅜ

결과적으로 MySQL Admin으로 받아온 SQL 덤프는 깨져있었다.
해서 SQLyog에서 다시 덤프를 받았다.
유니코드와 문제가 있다는 gFTP도 버리고 FileZilla로 다시 소스파일도 받았다.
phpmyadmin으로 import했던 sql dump도 command line mysql 명령으로 대체했다.
그렇게 해서 모든 중간단계에서 한글이 잘 읽히는데
마지막 브라우저에서는 여전히 일부 글자가 깨진다.
파일에서 읽어오는 한글은 제대로 나오는데 DB에서 읽어오는 글자들이 깨지는 걸보아
mysql_connect 쪽의 문제임을 직감했다.

해서 php mysql api쪽을 뒤지는데
mysql_client_encoding()이라는 함수가 눈에 띄었다.
커넥션 객체를 파라미터로 받아서 현재 사용중인 인코딩을 리턴해주는 함수. 오호라.
찍어봤더니 아니나 다를까 latin1으로 찍힌다.
난 설정화일을 euckr로 도배를 해놨는데 ㅡㅜ
이 latin1을 euckr로 바꾸려고 온갖 방법을 다 썼다.
하지만 바뀌지 않았다.

php manual에 보면 mysql_set_charset()이라는 매력적인 이름의 함수가 있는데 안타깝게도 php5부터 쓸 수 있는 녀석이었다. 지성이면 감천이랬던가 php4에서도 동작하는 mysql_set_charset()을 던져준 분이 있었으니
그의 이름은 vljubovic AT smartnet DOT ba


코드는 다음과 같다.
<?php
if (function_exists('mysql_set_charset') === false) {
   
/**
     * Sets the client character set.
     *
     * Note: This function requires MySQL 5.0.7 or later.
     *
     * @see http://www.php.net/mysql-set-charset
     * @param string $charset A valid character set name
     * @param resource $link_identifier The MySQL connection
     * @return TRUE on success or FALSE on failure
     */
   
function mysql_set_charset($charset, $link_identifier = null)
    {
        if (
$link_identifier == null) {
            return
mysql_query('SET NAMES "'.$charset.'"');
        } else {
            return
mysql_query('SET NAMES "'.$charset.'"', $link_identifier);
        }
    }
}
?>

이 녀석으로 db connection을 맺을때마다 강제로 set names 'euckr'을 실행시켜주면 결과값을 제대로 받아온다. 그리고 또 놀라운 사실은 제 아무리 euckr로 결과를 받아오고 있더라도 mysql_client_encoding()함수는 여전히 latin1을 반환하고 있다는 것.
알고보니 PHP4의 유명한 버그였더라 ㅜㅜ
이제 개발서버 세팅을 끝내고 제대로 일 좀 해야겠다.
본문인쇄본문메일발송
DB 백업 & 복원 (--default-character-set)
초보자를 위한「MySQL 백업·복구」강좌
Copyright 1999-2019 Zeroboard / skin by ChanBi