適切な文字セットをサーバーレベルで設定しておくのが理想だし、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');
?>
実行時に文字セットを変更する適切な方法を、各 API について示します。
例2 文字セットの設定: mysqli
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
if (!$mysqli->set_charset('utf8')) {
printf("Error loading character set utf8: %s\n", $mysqli->error);
} else {
printf("Current character set: %s\n", $mysqli->character_set_name());
}
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");
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);
?>