PHPのPDOクラスでのデータベース接続で、
<?php
$dsn = 'mysql:dbname=shop; host=localhost';
$user = 'root';
$password = ' ';
$dbh = new PDO($dsn, $user, $password);
$dbh->query('SET NAMES utf8');
みたいな記述が出てきて、『query('SET NAMES utf8');』の引数の意味を調べてみました。
結論として、『'SET NAMES utf8'』はSQLステートメント(SQL文)で、
『'SELECT * FROM mst_staff WHERE code = ?';』みたいに、データベースに対する命令文の一種らしいです。
「otukutunの日記」さんに載っていたんですが、『query('SET NAMES utf8')』を実行することで、MySQLのデータベースに情報を格納する時の文字化けを解消できるってことらしいです。
⇩ otukutunの日記(MySQLの文字化け対策に関して)は下記サイトへ
・PDO使って、MySQLに日本語データ突っ込んだら、文字化けした。 - otukutunの日記
とりあえず、結論出てしまったんで、ここから先はもう読む必要ないと思いますが、時間のある方は読んでみてください。
PHP: PDO::query - Manual によるとquery( )メソッド(PDOクラス)の説明は、
PDO::query
説明
public PDOStatement PDO::query ( string $statement
)
public PDOStatement PDO::query ( string $statement
,int $PDO::FETCH_COLUMN
, int $colno
)
public PDOStatement PDO::query ( string $statement
,int $PDO::FETCH_CLASS
, string $classname
, array$ctorargs
)
public PDOStatement PDO::query ( string $statement
,int $PDO::FETCH_INTO
, object $object
)
PDO::query( ) は、一回の関数コールの中で SQL ステートメントを実行し、このステートメントにより返された 結果セット (ある場合) を PDOStatement オブジェクトとして返します。
複数回発行する必要があるステートメントの場合、 PDO::prepare( )で PDOStatement ステートメントを準備し、PDOStatement::execute( ) でそのステートメントを 複数回発行する方がより良いパフォーマンスを得られると実感するでしょう。
PDO::query( ) を次にコールする前に 結果セット内の全てのデータを取得しない場合、そのコールは失敗します。
PDOStatement::closeCursor( ) をコールし、 次に PDO::query( ) をコールする前に PDOStatement オブジェクトに関連付けられたリソースを解放してください。
パラメータ(引数) ¶
返り値
PDO::query( ) は、PDOStatement オブジェクトを返します。 失敗した場合は FALSE
を返します。
例1 PDO::query の例
PDO::query( ) の優れた機能は、 実行に成功したSELECTステートメントにより返されたレコードセットで 反復処理が可能であることです。
<?php
function getFruit($conn) {
$sql = 'SELECT name, color, calories FROM fruit ORDER BY name';
foreach ($conn->query($sql) as $row) {
print $row['name'] . "\t";
print $row['color'] . "\t";
print $row['calories'] . "\n";
}
}
?>
上の例の出力は以下となります。
apple red 150 banana yellow 250 kiwi brown 75 lemon yellow 25 orange orange 300 pear green 150 watermelon pink 90
参考
- PDO::exec( ) - SQL ステートメントを実行し、作用した行数を返す
- PDO::prepare( ) - 文を実行する準備を行い、文オブジェクトを返す
- PDOStatement::execute( ) - プリペアドステートメントを実行する
パラメータ(引数)の説明で、$statement(型:文字列 )が準備、発行するSQLステートメントとなっていて、MySQLマニュアルの MySQL :: MySQL 5.6 リファレンスマニュアル :: 10.1 文字セットのサポート の説明によると、
『MySQL では、さまざまな文字セットを使用してデータを格納し、さまざまな照合順序に従って比較を実行できます。』
『サーバー、データベース、テーブル、およびカラムレベルで文字セットを指定できます。』
『MySQL では、MyISAM、MEMORY、および InnoDB のストレージエンジンの文字セットの使用をサポートします。』
『文字セットの問題は、データストレージだけではなく、クライアントプログラムと MySQL Server との通信にも影響を与えます。』
『デフォルトと異なる文字セットを使用してクライアントプログラムとサーバー間の通信を行う場合、どの文字セットを使用するのかを示す必要があります。』
『たとえば、utf8 Unicode 文字セットを使用するには、サーバー接続後に次のステートメントを発行してください。
SET NAMES 'utf8';
』
そして、PHPマニュアルの文字セットに関する関数のPHP: mysql_set_charset - Manual の説明で、
mysql_set_charset
説明
bool mysql_set_charset ( string $charset
[, resource$link_identifier
= NULL ] )
現在の接続における、デフォルトの文字セットを設定します。
パラメータ¶
charset
-
有効な文字セット名。
link_identifier
-
MySQL 接続。 指定されない場合、mysql_connect( ) により直近にオープンされたリンクが 指定されたと仮定されます。
そのようなリンクがない場合、引数を指定せずにmysql_connect( ) がコールした時と同様にリンクを確立します。
リンクが見付からない、または、確立できない場合、E_WARNING
レベルのエラーが生成されます。
返り値
成功した場合に TRUE
を、失敗した場合に FALSE
を返します。
注意 ¶
参考
『MySQLの文字セットの概念を参照ください。』とあるので調べると、
文字セット
適切な文字セットをサーバーレベルで設定しておくのが理想だし、MySQL のマニュアルの » Character Set Configuration にもそうするよう書かれています。
しかしそれ以外にも、各 MySQL API には実行時に文字セットを指定する方法が用意されています。
例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 について示します。
例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);
?>
PDOクラスで使っている例が無かったのですが、 query( )メソッドはパラメータ(引数)に『準備、発行するSQLステートメント(SQL文)』を取ると書いてあったんで、PDOクラスでも使えるってことだと思います。
今回はこのへんで。