勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

PHPでmysqli関数使用時のプリペアドステートメントの利用方法

  PHP MySQL データベース

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側でキャッシュが効くようになり、実行速度アップが見込める。

 - PHP MySQL データベース

  関連記事

MySQLで「server has gone~」というエラーの対応方法

MySQLで「MySQL server has gone away」というエラー ...

MySQLでWhere句をつけてdumpファイルを出力する方法

MySQLであるテーブルからWhere句をつけて、絞った結果をダンプさせたかった ...

PHPからMySQLにシリアライズしたデータを格納

アンケートフォームみたいなのがあって、 今後も定期開催し、尚且つ質問内容は増減す ...

MySQLのREGEXPで半角記号を検索したい場合の対応方法

MySQLのREGEXPで半角記号を検索したい場合\\を付けてエスケープしないと ...

MySQLのtinyintのカラムにbool値を入れた場合

他所のシステムに携わることがあり中身を色々見ているとMySQLでtinyint( ...