그누보드에 이모지,이모티콘 가능하게 MySQL 5.7버전에 세팅방법 > 개발자팁

개발자팁

개발과 관련된 유용한 정보를 공유하세요.
질문은 QA에서 해주시기 바랍니다.

그누보드에 이모지,이모티콘 가능하게 MySQL 5.7버전에 세팅방법 정보

웹서버 그누보드에 이모지,이모티콘 가능하게 MySQL 5.7버전에 세팅방법

본문


euckr 에서 utf8넘어온후에 DB문자셋 변경할일 없을줄알았는데..

아래 그림은 이모지의 코드번호 캡춰화면이다  .

이모티콘 그림을  문자로 만들어 놓은것으로 생각된다.

그것도 모르고 여적 문자가 아닌 그림인 줄알았다. ^^ -_-;

한글URL주소 처럼 이모티콘URL주소도 가능하고 , text 이모티콘 검색어로도 가능하다.

카톡에 이모티콘(이모지) 문자포함된글을  게시판에 붙어넣었더니글이 짤리는 버그가 발견되었다.

왜그런가 한참을 원인 분석하다가 결국 이모티콘 특수문자에서 잘린것을 알았다.

그리고 어떤떄엔  이모지, 이모티콘이 모두 물음표(????) 로만 나왔다.

이젠 그누보드도 게시판 글쓰기 오류를 패치해야할 때가 온것같다.~

 

-------------이모지(이모티콘) utf8mb4코드 ( 4바이트)===

3554563909_1601103513.9541.png

--------------------------------------------------------------------그림1-------

 

 

1) utf8 문자셋(3바이트)을 utf8mb4 로  4바이트 문자셋으로 바꿔야한다.

2)정렬은 utf8_general_ci 가 아닌 utf8mb4_general_ci 혹은 utf8_unicode_ci 로 collation 해줘야.

3) MySQL 5.7이상 업그레이드 필요.

4)​ 카톡,네이버 구글 ,주소창 모두 이모지 문자가 먹힌다. gnu에서는 현재 물음표(?) 로 표시된다.

어떤것은 이모지문자후에 글자가 잘린다.

---------- 변환 시작 -----

1. DB 기본세팅 변경

ALTER TABLE `yourDBName`.`yourTableName` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

2. Table 변경 프로그램 가동한다. 

<?php
/**
 * Requires php >= 5.5
 *  
 * This is a PHP port from: https://gist.github.com/njvack/6113127
 *
 *이것을 하기전에 백업하세요. mysqldump -h localhost -u root -pYourPW  yourDBName >  yourDbName_bakup.sql
 *
 * DB는  utf8 시작 입니다.
 *
 * $dsn = 'mysql:host=localhost;port=3306;charset=utf8';
 * 
 *  한번만 실행하면 끝나는데.  에러나만 계속 새로고침 합니다.  
 *
 * @author hollodotme *
 * @author derclops since 2019-07-01
 *         - convert the database to utf8mb4
 *         - convert all tables to utf8mb4
 *         - actually then also convert the data to utf8mb4

아래는 위에 저작자분이 만든것을 일부수정 ydb=YurDBName  넣어서 쓸수있게 하였고 lantin1 을  utf8로 하였음. 

이소스를 my_cvt_utf8to_utf8mb4.php로저장했다면 

  http://localhost/my_cvt_utf8to_utf8mb4.php?ydb=YurDbName   이런식으로  실행합니다.

 */
 
error_reporting( E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_ERROR | E_WARNING | E_PARSE | E_USER_ERROR | E_USER_WARNING );

$ydb=$_GET['ydb'];
if(!$ydb) {echo "<h1>ydb=</h1>"; exit ; }

$dsn      = 'mysql:host=localhost;port=3306;charset=utf8';
$user     = 'root';
$password = 'YOUR_PW';
$options  = [
    \PDO::ATTR_CURSOR                   => \PDO::CURSOR_FWDONLY,
    \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
    \PDO::MYSQL_ATTR_INIT_COMMAND       => "SET CHARACTER SET utf8",
];


header('Content-Type: text/plain; charset=utf-8');

$oDb = new \PDO( $dsn, $user, $password, $options );

$databasesToConvert = [ $ydb/** database3, ... */ ];
$typesToConvert     = [ 'char', 'varchar', 'tinytext', 'mediumtext', 'text', 'longtext' ];

foreach ( $databasesToConvert as $database )
{
    echo $database, ":\n";
    echo str_repeat( '=', strlen( $database ) + 1 ), "\n";

    $oDb->exec( "USE `{$database}`" );

    echo "converting database to correct locale too ... \n";

    $oDb->exec("ALTER DATABASE `{$database}` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci");


    $tablesStatement = $oDb->query( "SHOW TABLES" );
    while ( ($table = $tablesStatement->fetchColumn()) )
    {
        echo "Table: {$table}:\n";
        echo str_repeat( '-', strlen( $table ) + 8 ), "\n";

        $columnsToConvert = [ ];

        $columsStatement = $oDb->query( "DESCRIBE `{$table}`" );

        while ( ($tableInfo = $columsStatement->fetch( \PDO::FETCH_ASSOC )) )
        {
            $column = $tableInfo['Field'];
            echo ' * ' . $column . ': ' . $tableInfo['Type'];

            $type = preg_replace( "#\(\d+\)#", '', $tableInfo['Type'] );

            if ( in_array( $type, $typesToConvert ) )
            {
                echo " => must be converted\n";

                $columnsToConvert[] = $column;
            }
            else
            {
                echo " => not relevant\n";
            }
        }


        //convert table also!!!
        $convert = "ALTER TABLE `{$table}` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci";

        echo "\n", $convert, "\n";
        $oDb->exec( $convert );
        $databaseErrors = $oDb->errorInfo();
        if( !empty($databaseErrors[1]) ){
            echo "\n !!!!!!!!!!!!!!!!! ERROR OCCURED ".print_r($databaseErrors, true)." \n";
            exit;
        }


        if ( !empty($columnsToConvert) )
        {
            $converts = array_map(
                function ( $column )
                {
                    //return "`{$column}` = IFNULL(CONVERT(CAST(CONVERT(`{$column}` USING utf8) AS binary) USING utf8mb4),`{$column}`)";
                    return "`{$column}` = CONVERT(BINARY(CONVERT(`{$column}` USING utf8)) USING utf8mb4)";
                },
                $columnsToConvert
            );

            $query = "UPDATE IGNORE `{$table}` SET " . join( ', ', $converts );

            //alternative
            // UPDATE feedback SET reply = CONVERT(BINARY(CONVERT(reply USING utf8)) USING utf8mb4) WHERE feedback_id = 15015;


            echo "\n", $query, "\n";


            $oDb->exec( $query );

            $databaseErrors = $oDb->errorInfo();
            if( !empty($databaseErrors[1]) ){
                echo "\n !!!!!!!!!!!!!!!!! ERROR OCCURED ".print_r($databaseErrors, true)." \n";
                exit;
            }
        }

        echo "\n--\n";
    }

    echo "\n";
}
?>

 

이것을 실행하게되면 아래 에러가 발생하는경우 있다.

==아래 에러코드 == <code>

 

!!!!!!!!!!!!!!!!! ERROR OCCURED Array ( [0] => 42000 [1] => 1071 [2] => Specified key was too long; max key length is 1000 bytes )

 

에러마다 alter table 해서 필드 크기를 줄여줘야한다.  끝날때까지 새로고침. 계속 해준다.

<code>#예제

 

alter table `g5_apms_cache` change `c_name` `c_name` varchar(200) NOT NULL DEFAULT '' ;

끝까지 필드 에 맞게 계속 반복..


/common.php 파일수정 

#이부분 을 찾아

    $connect_db = sql_connect(G5_MYSQL_HOST, G5_MYSQL_USER, G5_MYSQL_PASSWORD) or die('MySQL Connect Error!!!'); 
    $select_db  = sql_select_db(G5_MYSQL_DB, $connect_db) or die('MySQL DB Error!!!');       
    // mysql connect resource $g5 배열에 저장 - 명랑폐인님 제안
    $g5['connect_db'] = $connect_db; 

    #이건 빼고 --    sql_set_charset('utf8', $connect_db); 

    #++ 아래 추가. 

        define('G5_NAMES','utf8mb4');

        sql_set_charset(G5_NAMES , $connect_db); 
        if( G5_NAMES =="utf8mb4" )$utf8_general_ci="utf8mb4_unicode_ci";

        sql_query("set session character_set_connection=".G5_NAMES);
        sql_query("set session character_set_results=".G5_NAMES);
        sql_query("set session character_set_client=".G5_NAMES);
        if($utf8_general_ci) sql_query("SET collation_connection = $utf8_general_ci ");  

 

#/adm/dbupdate.php 파일수정

  # $COLL 을 원하는곳 common.php나 config.php에  선언해두고 alter table 혹은 create table 등 코드중간에 $COLL을 넣어준다. 
  $COLL ="COLLATE utf8mb4_unicode_ci ";
  

  dbupdate.php 파일의  sql문장 varchar 중간에 $COLL 을 넣어준다,  varchar(200) $COLL 식으로.

 

    #++  끝

 

my.cnf 파일 수정해도 되고 안해도되고

[mysqld]

character-set-server=utf8mb4

collation-server=utf8mb4_unicode_ci

 

이상으로 이모지, 이모티콘 변환방법을 마칩니다.

 

다음엔 시간나면 새로추가된 이모지, 이모티콘 특수문자에 대해서 ~ 쓰고싶어짐니다.^^

도움이 되셨다면 좋아요  꾹~ (그러면  글쓰는 이에게  힘이 되곘죠!)

 2020.9.26

수다원 올림.

참고: https://github.com/emoji/emoji.github.com

 

 

추천
4

댓글 7개

요새 MariaDB는 utf8mb4가 기본이더라구요 ㅎㅎ

그래서 처음에 설치하기 전에 config.php를 열어서 utf8을 utf8mb4로 바꾸면 되더군요.
아하 그러쿤요~ 정보 감사합니다.
MariaDB 앞서가는군요..
새로 깔지는 못하고 관리만 계속 하다보니 그걸 몰랐네요~
config.php에서 utf8 고정시킨것이 있는줄 모르고..
DB모두 변환완료후 계속  이모지가 ??로 나와서  몇일간 삽질 했네요.
결국 소스 1/2 씩 삭제해가면서 Line별로 echo넣어가면서 결국 찾답니다.
기존설치되어있는경우
common.php에서
sql_set_charset('utf8', $connect_db);를
sql_set_charset('utf8mb4', $connect_db); 로 변환해주고

데이터베이스 에디터에서 적용하고픈 테이블에
ALTER TABLE  테이블명    CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;  해주면 그냥 잘 적용이 되요

문제점이 있을런지는 모르겠는데..
전체 111
개발자팁 내용 검색 웹서버에서

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT