PHPでmysqli関数使用時のプリペアドステートメントの利用方法
PHPでMySQLを扱う際はmysqli関数を、エスケープの際はreal_escape_stringを使用していた。ただ他社のソースコードを見るとpdo / mysqliどちらを使うにしてもプリペアドステートメントで書かれていることが多いように思う。そこでプリペアドステートメントの書き方を覚えておきたい。
データベース構造
mysql> SHOW COLUMNS FROM test_table; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | int | NO | PRI | NULL | auto_increment | | name | varchar(255) | NO | | NULL | | | score | int | NO | | NULL | | | regist_ymd | datetime | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+
ソースコード
INSERT
$stmt = $mysqli->prepare("
INSERT INTO test_table
(name, score, regist_ymd)
VALUES
(?, ?, now())
");
$name = '山田';
$score = 50;
$stmt->bind_param('si', $name, $score);
$res = $stmt->execute();
$stmt->close();
UPDATE
$stmt = $mysqli->prepare("
UPDATE test_table
SET name = ?
WHERE id = ?
");
$name = '高橋';
$id = 1;
$stmt->bind_param('si', $name, $id);
$res = $stmt->execute();
$stmt->close();
SELECT
$stmt = $mysqli->prepare("
SELECT *
FROM test_table
WHERE score > ?
");
$score = 70;
$stmt->bind_param('i',$score);
$stmt->execute();
$result = $stmt->get_result();
while($row = $result->fetch_array(MYSQLI_ASSOC)){
var_dump($row);
}
DELETE
$stmt = $mysqli->prepare("
DELETE FROM test_table
WHERE id = ?
");
$id = 1;
$stmt->bind_param('i', $id);
$res = $stmt->execute();
$stmt->close();
解説等
bind_param
第1引数にバインド変数の型を記述する必要あり。型指定文字は以下の通り。
- i → int
- d → float
- s → string
- b → blob
バインドする変数が「文字列、数値、文字列」の場合は「sis」のように記述する。
execute
プリペアドステートメントの実行。成否により戻り値がtrue / falseになるのでエラーチェックの際は「if( $stmt->execute() )」とかになりそう。
エラー対応
Fatal error: Uncaught mysqli_sql_exception: Unknown column 'xxx' in 'field list' in
(カラム名が間違っている等で)カラムが見つからない場合に発生するエラー。例えばだけど今回の場合「score」というカラムを「point」とかで書いちゃうとエラー。
カラム名に間違いが無いか確認すること。
Fatal error: Uncaught mysqli_sql_exception: Column count doesn't match value count at row
バインド変数とカラム数が合わない場合に発生するエラー。どちらかに抜けが無いか確認すること。
プリペアドステートメントのメリット
エスケープが不要
公式案内にも書かれているようにエスケープが不要になる。
キャッシュが効くので実行速度アップ
MySQL側でキャッシュが効くようになり、実行速度アップが見込める。
関連記事
-
-
WordPressでデータベース接続確立エラー発生時の対応方法
WordPressで「データベース接続確立エラー」というエラー表示がされた。大抵 ...
-
-
MySQLでテーブルとデータの複製(コピー)する方法
MySQLでテーブルとデータを複製したかった。ダンプとかではなく、簡単なSQL文 ...
-
-
MySQLで文字列を置換する方法
MySQLで文字列の置換を行いたかった。以下に方法をメモ。 目次1 ...
-
-
異なるVPS間でMySQLの接続を行う方法
異なるVPS間でMySQL接続を行った際のメモ。 目次1 対応方法 ...
-
-
MySQLで直近〇日、〇ヶ月、〇年以内のデータを検索する方法
他社が作成されたSQL文を見ているとDATE_ADDという使ったことの無い関数が ...