The 5th Annual China PHP Conference

文字セット

適切な文字セットをサーバーレベルで設定しておくのが理想だし、MySQL のマニュアルの » Character Set Configuration にもそうするよう書かれています。 しかしそれ以外にも、各 MySQL API には実行時に文字セットを指定する方法が用意されています。

警告

文字セットと文字のエスケープ

文字セットはきちんと理解して設定しておかないといけません。 すべての操作に影響が及ぶし、セキュリティの問題を引き起こす可能性があるからです。 たとえば、文字列のエスケープ (mysqli なら mysqli_real_escape_string()、 mysql なら mysql_real_escape_string()、 そして PDO_MySQL なら PDO::quote()) は文字セットの設定に従った動きをします。 これらの関数は、クエリで設定した文字セットは使わないことを知っておくことが大切です。 たとえば次の例のような設定をしても、エスケープ機能は正しく動きません。

例1 文字セットを SQL で指定することによる問題

<?php

$mysqli 
= new mysqli("localhost""my_user""my_password""world");

// これは $mysqli->real_escape_string(); に影響を及ぼしません
$mysqli->query("SET NAMES utf8");

// これも $mysqli->real_escape_string(); に影響を及ぼしません
$mysqli->query("SET CHARACTER SET utf8");

// しかしこの方法なら $mysqli->real_escape_string(); にもきちんと影響します
$mysqli->set_charset('utf8');

// いっぽう、こちらは影響を及ぼしません (utf-8 と utf8 の違いに注目) -- ここではハイフンを使ってはいけません
$mysqli->set_charset('utf-8');

?>

実行時に文字セットを変更する適切な方法を、各 API について示します。

注意: UTF-8 でありがちなミス

MySQL の文字セット名はハイフンを含まないので、MySQL で UTF-8 を表す文字セットは "utf8" が正解です。"utf-8" ではないので、"utf-8" と指定しても文字セットは変わりません。

例2 文字セットの設定: mysqli

<?php

$mysqli 
= new mysqli("localhost""my_user""my_password""world");

printf("Initial character set: %s\n"$mysqli->character_set_name());

if (!
$mysqli->set_charset('utf8')) {
    
printf("Error loading character set utf8: %s\n"$mysqli->error);
    exit;
}

echo 
"New character set information:\n";
print_r$mysqli->get_charset() );

?>

例3 文字セットの設定: pdo_mysql

注意: これは PHP 5.3.6 以降でしか動作しません。

<?php
$pdo 
= new PDO("mysql:host=localhost;dbname=world;charset=utf8"'my_user''my_pass');
?>

例4 文字セットの設定: mysql

<?php
$conn 
mysql_connect("localhost""my_user""my_pass");
$db   mysql_select_db("world");

echo 
'Initial character set: ' .  mysql_client_encoding($conn) . "\n";

if (!
mysql_set_charset('utf8'$conn)) {
    echo 
"Error: Unable to set the character set.\n";
    exit;
}

echo 
'Your current character set is: ' .  mysql_client_encoding($conn);
?>
add a note add a note

User Contributed Notes 1 note

up
-27
go at NOSPAMME dot quidera dot com
4 years ago
If none of the character set alterations work and the data is valid UTF8 and is garbled when saved in mysql. Then your table is not supporting UTF8 and likely is Latin1 or something else. So  you will need to update you table, in the case of MySQL do the following:

ALTER TABLE <table_name> CONVERT TO CHARACTER SET utf8;
To Top