MySQL 4.1 이상 + PHP 프로그램의 웹브라우저에서 한글이 깨지는 문제 해결 방법.

기본적으로 mysql 4.1의 서버와 mysql(client) 에서 한글 (euckr로가정)을 제대로 입출력하기 위해서는 몇가지 설정이 필요합니다.

특히 옛날에 character set을 db자체에 저장하지 않던 구조의 database를 가지고 있는 경우 더욱 그렇습니다.

제 환경은 Redhat 7.3 , MySQL 4.1.8 (RPM),PHP 5.0.3,Apache 1.3.33 입니다.

 

MySQL의 설정파일이 /etc/my.cnf 라고 가정 합니다.

 

 

위 3 세션에 모두

default-character-set=euckr

이라는 내용을 있으면 놔두고 없으면 추가해주십시요. 다른 언어로 되어있다면 그부분만 euckr 로 수정하시면 됩니다.

참고로 4.1부터는 euc_kr에서 euckr로 바뀌었습니다.

 

db에 character set 정보가 저장되지 않았던 시절에 만들어진 db들의 경우 위의 설정을 바꾸께되면 database 의 코드가 바뀌어 버리게 됩니다. 그러니 이전에 사용하던것과 일치시켜 주셔야 합니다.

 

일단 이렇게까지만하면 콘솔에서 mysql 을 실행하여 접속해서 한글을 읽고 쓰는대는 별문제가 없으실 것입니다. 그러나 제경우 문제는 이뒤부터 발생했습니다.

웹에서 출력하는 페이지들중 db에서 불러오는것들이 ASCII 가 문자들의 경우 모두 ? 로 깨어저 나오는 것입니다.

 

그래서 직감적으로 character set에 관련된 문제란건 알겠는데 이것을 확인하는 방법부터 말씀 드리면

 

shell에서

mysql dbname -e ‘show variables like “%character%”;show variables like “%collation%”;’

 

이렇게 입력해보시면 아마도 위의 3 세션 모두 정상적으로 수정해서 적용되었다면

( 세션의 경우 mysql 서버 재시작 필요.dbname을 mysql 등으로 바꿔서 해주시기 바랍니다.)

이렇게 나올 것입니다.

 

 

Variable_name Value
character_set_client euckr
character_set_connection euckr
character_set_database euckr
character_set_results euckr
character_set_server euckr
character_set_system utf8
character_sets_dir /usr/share/mysql/charsets/
Variable_name Value
collation_connection euckr_korean_ci
collation_database euckr_korean_ci
collation_server euckr_korean_ci

 

그러나 shell에서 실행하는 client의경우 세션의 영향을 받는데 (다른 character set으로 바꾸면서 실행해보시면 확실히 아실 수 있습니다.)

 

웹에서 php를 이용하여 접속한것들은 적용이 안되는것을 확인햇습니다.

확인하는 코드는 아래와 같습니다.

 

show variables like “%character%”;show variables like “%collation%”;

 

이것을 브라우저를 통해 실행해서 실제로 php를 이용한 접속에서 도대체 character 에 어떤 문제가 발생하는지 볼수 있습니다.

 

실행결과는 아래와 비슷할 것입니다.

character_set_client | latin1
character_set_connection | latin1
character_set_database | euckr
character_set_results | latin1
character_set_server | euckr
character_set_system | utf8
character_sets_dir | /usr/share/mysql/charsets/

collation_connection | latin1_swedish_ci
collation_database | euckr_korean_ci
collation_server | euckr_korean_ci

 

character가 shell에서 실행할때와는 완전히 딴판인것을 눈으로 직접 확인할 수 잇습니다.

그럼 이것을 해결해야되는데 이것은

 

mysql 서버에 접속시

set session character_set_connection=euckr;
set session character_set_results=euckr;
set session character_set_client=euckr;

 

들을 실행하여 character set에 대한 정의를 다시 해주시면 됩니다.

 

자 순서대로 어던일이 일어나는지 봅시다.바로 위의 3가지 character set설정 명령없이 실행한경우와 비교해 보시기 바랍니다.

그럼 해당 설정들이 실제로 어떤 영향을 미치는지 이해하는데 도움이 될것입니다.

 

먼저 set session character_set_connection=euckr; 만 적용할 경우.

결과는 아래와같습니다. 3가지중 아무것도 적용안했을경우와 비교하면

character_set_client | latin1
character_set_connection | euckr    <== latin1 에서 euckr 로 변경됨.
character_set_database | euckr
character_set_results | latin1
character_set_server | euckr
character_set_system | utf8
character_sets_dir | /usr/share/mysql/charsets/

collation_connection | euckr_korean_ci    <== latin1_swedish에서 euckr로 변경됨
collation_database | euckr_korean_ci
collation_server | euckr_korean_ci

 

 

 

이제 set session character_set_results=euckr; 만 적용해 봅시다.

결과는 아래와 같습니다.3가지중 아무것도 적용안했을경우와 비교하면

 

character_set_client | latin1
character_set_connection | latin1
character_set_database | euckr
character_set_results | euckr      <== latin1 에서 euckr로 변경됨
character_set_server | euckr
character_set_system | utf8
character_sets_dir | /usr/share/mysql/charsets/

collation_connection | latin1_swedish_ci
collation_database | euckr_korean_ci
collation_server | euckr_korean_ci

이제 set session character_set_client=euckr; 만 적용해 보면 결과는

아래와 같습니다.3가지중 아무것도 적용안했을경우와 비교하면

 

character_set_client | euckr         <== latin1에서 euckr로 변경됨
character_set_connection | latin1
character_set_database | euckr
character_set_results | latin1
character_set_server | euckr
character_set_system | utf8
character_sets_dir | /usr/share/mysql/charsets/

collation_connection | latin1_swedish_ci
collation_database | euckr_korean_ci
collation_server | euckr_korean_ci

이제 3가지를 모두 한번에 적용해 봅시다.

set session character_set_connection=euckr;
set session character_set_results=euckr;
set session character_set_client=euckr;

결과는 아래와 같습니다.3가지중 아무것도 적용안했을경우와 비교하면

character_set_client | euckr                  <== latin1에서 euckr로 변경됨.
character_set_connection | euckr          <== latin1에서 euckr로 변경됨.
character_set_database | euckr
character_set_results | euckr                <== latin1에서 euckr로 변경됨.
character_set_server | euckr
character_set_system | utf8
character_sets_dir | /usr/share/mysql/charsets/

collation_connection | euckr_korean_ci    <== latin1에서 euckr 로 변경됨.
collation_database | euckr_korean_ci
collation_server | euckr_korean_ci

이제 원하시는대로 웹브라우저의 encoding 이 한국어로 되있을경우 안깨지는 정상적인 결과를 얻을실 수 있을 것입니다.

 

완전히 새로 만들고 다국어데이타의 입력도 고려한다면 unicode의 사용도 괜찮을듯 싶습니다.

 

 

위에서 php통하여 실행시키는 코드는 아래와 같습니다.

localhost로 접속하고 암호는 없으며 db계정을 root라 가정합니다.

 

//  php 프로그램의 시작

<?

$connect    = mysql_connect(localhost,root);
$isResult    = mysql_select_db(“mysql”, $connect
);

// mysql_query(“set session character_set_connection=euckr;”);
// mysql_query(“set session character_set_results=euckr;”);
// mysql_query(“set session character_set_client=euckr;”);

$sql = “show variables like ‘%character%'”;
$result = mysql_query($sql
);

while($row = mysql_fetch_array($result)) {
echo $row[0] . ” | ” . $row[1] . “<br>\n”
;
}

echo (“<br><br>”);

$sql = “show variables like ‘%collation%'”;

$result = mysql_query($sql);

while($row = mysql_fetch_array($result)) {
echo $row[0] . ” | ” . $row[1] . “<br>\n”
;
}

?>
// php 프로그램의 끝

 

프로그램을 붙여넣기 하여 파일로 저장한후 3가지 설정의 주석을 풀아가면서 또 모두 풀어서 테스트 해보시기 바랍니다.(굵게 표시된 부분)

 

 

혹시 내용상 오류가 있을지 모르니 리플좀 부탁드립니다.

참고로 system에 utf8의 경우 고정되어있는 값으로 변경 불가능 합니다.

5.0 버젼 부터는 클라이언트 쪽에서 set names utf8 또는 set names euckr등을 통해서 클라이언트가 사용하는 문자셋을 편하게 지정할 수 있습니다.

답글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

*