MySQL関数のまとめ

MySQLサーバに接続する
MySQLのクエリを実行する
文字列をエスケープする
文字セットを変更する
SELECTなどの結果セットの扱い方
複数のデータベースに接続する

[参考記事] MySQLで文字コードを指定する方法
[参考記事] 日付型のフォーマットにスラッシュを使ってはいけません(文字コードによって値が変わる)

MySQLサーバに接続する

[参考記事] MySQLサーバに接続できるかどうかを確認する

// データベースサーバへの接続を試みる
if (!$con = @mysql_connect($server,DB_USERNAME,DB_PASSWORD)){
  print "Can not connect Server! host or username or password is wrong";
  exit;
}

// データベースへの接続を試みる
if(!mysql_select_db(DB_DATABASE,$con)){
  print "Can not connect Database! database name is wrong";
  exit;
}

MySQLのクエリを実行する

mysql_query(【SQL文】);

このときの戻り値は、エラーの場合、falseを返します。
成功した場合、結果セットを返すSQL文(SELECT、SHOW、DESCRIBE、EXPLAINなど)では、resource を返し、 結果セットを返さないSQL文(DELETE、INSERT、REPLACE、UPDATEなど)では、trueを返します。

エラーの場合エラーメッセージはmysql_error()、エラー番号はmysql_errno()で受け取れます。
たとえばエラーが発生した場合に処理を停止して、SQLのエラーメッセージを表示させるには次のようにします。

if(!mysql_query ($sql)){
	die(mysql_errno() . ':' . mysql_error());
}

if文は、空やブランクでもfalseと同様に扱いますが、SELECT文のmysql_queryの戻り値は結果が0件であってもResource idを返すので, 次のようなコードでもSQL文でエラーが発生しない限りif文の中は通りません。

if(!$resource = mysql_query (【結果がヒットしないSELECT文】)){
	die(mysql_errno() . ':' . mysql_error());
}

SELECT文によって返された行の数を知るには mysql_num_rows() を用います。
また DELETE、INSERT、REPLACEまたはUPDATE文で変更された行の数を知るには mysql_affected_rows() を用います。
INSERT文で挿入された自動採番(AUTO INCREMENT)の値を知るには mysql_insert_id() を用います。

文字列をエスケープする

INSERTやUPDATE文、WHERE句などで値をMySQLで実行できるようエスケープするにはmysql_real_escape_string()を使用します。
エスケープする関数には、ほかに mysql_escape_string()がありますが、この関数はPHP5.3.0で非推奨になっています。
mysql_real_escape_string()は現在の接続の文字セットで特殊文字をエスケープしますが、mysql_escape_string()は文字セットを考慮しません。
このためエスケープにはmysql_escape_string()ではなく、mysql_real_escape_string()を使用するようにします。

エスケープされる文字

NULL (null文字)0x00
\n LF(改行)0x0a
\r CR(復帰)0x0d
\ 0x5c
' (シングルクオート)0x27
" (ダブルクオート)0x22
SUB (置換)0x1a

LIKE演算子での『 % 』や『 _ (アンダーバー)』はエスケープされません。

たとえば『 %test" aaaa\ 』は『 %test\" aaaa\\ 』になります。

$str = "%test\" aaaa\\";
$str = mysql_real_escape_string($str);
print_r($str);

%test\" aaaa\\

スポンサーリンク

文字セットを変更する

[参考記事] MySQLで文字コードを指定する方法
[参考記事] 日付型のフォーマットにスラッシュを使ってはいけません(文字コードによって値が変わる)

SQL文で文字セットを変更するには、SET NAMESを使用します。
UTF-8なら

SET NAMES utf8

ShiftJISなら

SET NAMES sjis

EUC-JPなら

SET NAMES ujis

ただSET NAMESで文字セットを変更する方法は、PHPでは推奨されません。
PHPでMySQLの文字セットを変更するには、mysql_set_charset()を使用します。

UTF-8なら

mysql_set_charset("utf8");

SET NAMESで文字セットを変更した場合、PHPの他のMySQL関数で文字セットの変更を判断できません。
たとえば、文字セット名を返すmysql_client_encoding()では、次のようにSET NAMESとmysql_set_charset()で結果が異なります。

mysql_query("SET NAMES sjis");
echo mysql_client_encoding();

utf8

mysql_set_charset("sjis");
echo mysql_client_encoding();

sjis

ただmysql_set_charset()が使用できるのはPHP5.2.3以上、MySQL5.0.7以上の場合です。

if (version_compare(PHP_VERSION,'5.2.3', '>=') && version_compare(mysql_get_server_info(),'5.0.7', '>=')) {
	mysql_set_charset("utf8");
}else{
	mysql_query("SET NAMES utf8");
}

SELECTなどの結果セットの扱い方

SELECT文で得られた結果行数はmysql_num_rows($resource)、結果行はmysql_fetch_array($resource)で得ることができます。

mysql_fetch_arrayは、添字配列と、カラム名をキーとする連想配列で行の値を返します。

if(!$resource = mysql_query ("SELECT id, name FROM testtable")){
	die(mysql_errno() . ':' . mysql_error());
}
$row_num = mysql_num_rows($resource);
for($i=0;$i<$row_num;$i++){
	$row = mysql_fetch_array($resource);
	echo $row['id'];
	echo $row['name'];
}

mysql_fetch_arrayは行がもうない場合には FALSE を返すので、whileを使用すると次のようになります。

if(!$resource = mysql_query ("SELECT id, name FROM testtable")){
	die(mysql_errno() . ':' . mysql_error());
}
$lists = array();
while($row = mysql_fetch_array($resource)){
	echo $row['id'];
	echo $row['name'];
}
mysql_fetch_assoc()カラム名をキーとする連想配列で行の値を返します。
mysql_fetch_row()添字配列
mysql_fetch_array()第二引数により違います。
MYSQL_ASSOC : 連想配列
MYSQL_NUM : 添字配列
MYSQL_BOTH : 連想配列と添字配列
デフォルト値はMYSQL_BOTH

結果レコードに同一名のカラムがあった場合には、mysql_fetch_assoc()やmysql_fetch_array()の連想配列では、 最後のものが優先されるので1つしかえることができません。
同一名のカラムを区別するには、mysql_fetch_array()やmysql_fetch_row()の添字配列を使用します。

複数のデータベースに接続する

複数のデータベースに接続するとき、mysql_connectの戻り値の接続IDでそれぞれを区別することができます。

mysql_query(SQL文, 接続ID)

1つの接続情報でそれぞれのデータベースに接続する権限がある場合は、SQL文で区別することもできます。

SELECT * FROM database1.table_name1
SELECT * FROM database2.table_name1

複数の接続IDで区別する場合は、mysql_connectのみを変更するだけでデータベースを変更できますが、 接続IDの数ほどMySQLサーバにはコネクションが張られるため、その分だけリソースを消費します。

MySQLサーバの最大接続数は次のmysqladminコマンドでわかります。

[root@hoge ~]# mysqladmin -u root -p variables | grep max_connections
Enter password:
| max_connections | 100   |

またはSQL文では次のようにします。

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 100   |
+-----------------+-------+

ちなみに最大接続数を変更するにはmax_connectionsで変更できます。
SQL文では

set global max_connections = 500;

my.iniでは

[mysqld]
max_connections=500

SQL文で変更した場合、MySQLサーバを再起動した時点で元の値に戻ります。

[root@hoge ~]# mysqladmin -u root -p extended-status | egrep '(Max|Threads_)'
Enter password:
| Max_used_connections              | 5          |
| Threads_cached                    | 0          |
| Threads_connected                 | 3          |
| Threads_created                   | 23         |
| Threads_running                   | 1          |
パラメータ意味
Max_used_connectionsこれまでに記録された同時接続数の最大値
Threads_connected現在開いている接続の数
Threads_created接続を処理するために生成されたスレッド数
Threads_runningスリープ状態になっていないスレッド数

Max_used_connectionsの最大値は、理論上max_connectionsの値より1大きい値になります。
max_connectionsで最大値に達しても、SUPER権限ユーザが接続できるよう1つ別枠で用意されているためです。

関連記事

スポンサーリンク

MINUTE関数 分を求める

ホームページ製作・web系アプリ系の製作案件募集中です。

上に戻る