PHP PDO : 문자셋, 이름 설정?


189

나는 이전의 정상적인 mysql_ * 연결에서 이것을 가지고 있었다.

mysql_set_charset("utf8",$link);
mysql_query("SET NAMES 'UTF8'");

PDO에 필요합니까? 그리고 어디서 가져야합니까?

$connect = new PDO("mysql:host=$host;dbname=$db", $user, $pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));

10
SQL 삽입으로 인해 "SET NAMES utf8"을 피해야합니다. 자세한 내용은 php.net/manual/en/mysqlinfo.concepts.charset.php 를 참조 하십시오.
masakielastic

문자 집합 문제가 있으면 utf8로 설정하는 것 외에는 선택의 여지가 없습니다. 테이크 아웃은 아래의 Cobra_Fast로 표시된 연결 문자열을 사용해야한다고 생각합니다 . 바인딩 된 매개 변수로 SQL 문을 준비하려면 PDO :: prepare를 사용하십시오.
user12345

1
@masakielastic, 그렇다면 어떻게 데이터 정렬을 "SET NAMES utf8 COLLATE utf8_unicode_ci"로 지정해야합니까
datasn.io September

답변:


460

연결 문자열에 다음과 같이 표시됩니다.

"mysql:host=$host;dbname=$db;charset=utf8"

그러나 PHP 5.3.6 이전에는 문자셋 옵션이 무시되었습니다. 이전 버전의 PHP를 실행중인 경우 다음과 같이해야합니다.

$dbh = new PDO("mysql:$connstr",  $user, $password);
$dbh->exec("set names utf8");

15
이 동작은 5.3.6에서 변경되었으며 현재 제대로 작동하고 있습니다.
igorw

15
UTF-8의 utf8 instaead이어야한다 "mysql : host = $ host; dbname = $ db; charset = utf8"
od3n

3
최신 버전의 PHP를 사용하는 경우 아래 답변을 무시하십시오. PHP 5.3.8에서 제대로 작동합니다.
kasimir

4
이 경우 데이터 정렬도 지정해야합니까? 'SET NAMES utf8 COLLATE utf8_unicode_ci'와 같은?
datasn.io

2
감사! 내 하루를 구했다!
Aleksandr

64

PHP 5.3.6 이전에는 문자셋 옵션이 무시되었습니다. 이전 버전의 PHP를 실행중인 경우 다음과 같이해야합니다.

<?php

    $dbh = new PDO("mysql:$connstr",  $user, $password);

    $dbh -> exec("set names utf8");

?>

1
개조 참고 사항 : 정답이며, 승인 된 답변이이 정보를 편집하기 1 년 전에 게시되었습니다.
dotancohen

42

이것은 아마도 가장 우아한 방법 일 것입니다.
PDO 생성자 호출에서 바로 위에서 언급 한대로 버그가있는 문자 세트 옵션을 피하십시오.

$connect = new PDO(
  "mysql:host=$host;dbname=$db", 
  $user, 
  $pass, 
  array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"
  )
);

나를 위해 잘 작동합니다.


1
내 이해는 이것이 PHP 5.3.0에도 버그가 있다는 것입니다. 이 경우 다음과 같이 이름이 아닌 번호를 참조하여 배열에 옵션을 입력해야합니다 array(1002 => 'SET NAMES utf8',...).
JDelage

힌트 주셔서 감사합니다! 다른 5.3.X 버전의 PHP를 실행하는 여러 프로덕션 시스템에서 위의 코드를 성공적으로 사용하고 있지만 실제로는 5.3.0이 아닙니다.
Jpsy

4
나는 내 의견은 데이터베이스 특정 옵션없이 더 우아한 될 수있다
Aalex 가비

사실, MYSQL_ATTR_INIT_COMMAND는 MySQL 데이터베이스에서만 사용할 수 있습니다 (각 db 유형에 사용 가능한 명령은 php.net/manual/de/pdo.drivers.php 의 하위 페이지 참조 ). 그러나 이것이 바로 OP가 요구 한 것입니다.
Jpsy

charset=utf8dsn 문자열을 전달 하면 작동합니다! 나는 전혀 문제 알아 내려고 노력했다 groups.google.com/d/msg/auraphp/syMS26Rz-q8/9laQr9tR4EoJ
하리 KT

16

완전성을 위해 실제로 PDO에서 MySQL에 연결할 때 인코딩을 설정하는 가지 방법이 있으며 사용 가능한 방법은 PHP 버전에 따라 다릅니다. 선호 순서는 다음과 같습니다.

  1. charset DSN 문자열의 매개 변수
  2. 실행 SET NAMES utf8으로 PDO::MYSQL_ATTR_INIT_COMMAND연결 옵션
  3. SET NAMES utf8수동으로 실행

이 샘플 코드는 다음 세 가지를 모두 구현합니다.

<?php

define('DB_HOST', 'localhost');
define('DB_SCHEMA', 'test');
define('DB_USER', 'test');
define('DB_PASSWORD', 'test');
define('DB_ENCODING', 'utf8');


$dsn = 'mysql:host=' . DB_HOST . ';dbname=' . DB_SCHEMA;
$options = array(
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);

if( version_compare(PHP_VERSION, '5.3.6', '<') ){
    if( defined('PDO::MYSQL_ATTR_INIT_COMMAND') ){
        $options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . DB_ENCODING;
    }
}else{
    $dsn .= ';charset=' . DB_ENCODING;
}

$conn = @new PDO($dsn, DB_USER, DB_PASSWORD, $options);

if( version_compare(PHP_VERSION, '5.3.6', '<') && !defined('PDO::MYSQL_ATTR_INIT_COMMAND') ){
    $sql = 'SET NAMES ' . DB_ENCODING;
    $conn->exec($sql);
}

세 가지 모두를 수행하는 것은 아마도 과도하게 사용됩니다 (배포하거나 재사용 할 수업을 작성하지 않는 한).


1
동등한 ODBC / Access가 있습니까? 이제 Oracle 및 MySQL PHP PDO UTF8 연결이 작동하지만 ODBC / Access에서 작동하지 않습니다.
Jan

2
아 그리고 절대 데이터베이스 비밀번호를 정의하지 마십시오. 그것들은 슈퍼 글로벌만큼이나 세계적이며, 암호로 작업 할 때는 좋지 않습니다.
Xesau

2

COLLATE utf8_general_ci로 데이터베이스를 작성하거나 사용하려는 데이터 정렬을 확인해야한다고 덧붙이고 싶습니다. 그렇지 않으면 의도하지 않은 다른 데이터 정렬로 끝날 수 있습니다.

phpmyadmin에서 데이터베이스를 클릭하고 작업을 선택하여 데이터 정렬을 볼 수 있습니다. 데이터베이스와 다른 데이터 정렬을 사용하여 테이블을 만들면 어쨌든 테이블이 데이터베이스 데이터 정렬로 끝납니다.

따라서 테이블을 작성하기 전에 데이터베이스의 데이터 정렬이 올바른지 확인하십시오. 희망이 몇 시간을 누군가를 구해줘 lol


1
"데이터베이스가 아닌 다른 데이터 정렬을 사용하여 테이블을 만들면 어쨌든 테이블이 데이터베이스 데이터 정렬로 끝납니다." 테이블 데이터 정렬이 데이터베이스 데이터 정렬보다 우선합니다. dev.mysql.com/doc/refman/5.5/en/charset-table.html
humble_wolf

2

DSN의 charset 옵션이 실제로 무시되므로 추가 쿼리가 필요하다고 생각합니다. 다른 답변의 의견에 게시 된 링크를 참조하십시오.

Drupal 7이 http://api.drupal.org/api/drupal/includes--database--mysql--database.inc/function/DatabaseConnection_mysql%3A%3A__construct/7 에서 수행하는 방식을 살펴보십시오 .

// Force MySQL to use the UTF-8 character set. Also set the collation, if a
// certain one has been set; otherwise, MySQL defaults to 'utf8_general_ci'
// for UTF-8.
if (!empty($connection_options['collation'])) {
  $this->exec('SET NAMES utf8 COLLATE ' . $connection_options['collation']);
}
else {
  $this->exec('SET NAMES utf8');
}

1
$conn = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);

1
이 답변은 정확하고 유용 할 수 있지만, 문제를 해결하는 데 도움이되는 방법을 설명하기 위해 설명과 함께 포함하는 것이 좋습니다. 이것은 작동을 멈추게하는 변경 (아마도 관련이없는)이 있고 사용자가 한 번 작동 한 방식을 이해해야하는 경우 특히 유용합니다.
Erty Seidohl

1
$con="";
$MODE="";
$dbhost = "localhost";
$dbuser = "root";
$dbpassword = "";
$database = "name";

$con = new PDO ( "mysql:host=$dbhost;dbname=$database", "$dbuser", "$dbpassword", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$con->setAttribute ( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );   

0

이 코드를 테스트하고

$db=new PDO('mysql:host=localhost;dbname=cwDB','root','',
array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$sql="select * from products  ";
$stmt=$db->prepare($sql);
$stmt->execute();
while($result=$stmt->fetch(PDO::FETCH_ASSOC)){                  
    $id=$result['id'];
}

이 코드는 질문에 대답 할 수 있지만,이 코드가 질문에 응답하는 이유 및 / 또는 방법에 대한 추가 컨텍스트를 제공하면 장기적인 가치가 향상됩니다.
rollstuhlfahrer

-1

$ con = 새로운 PDO ( "mysql : host = $ dbhost; dbname = $ database; charset = $ encoding ", "$ dbuser", "$ dbpassword");

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.