勉強したことのメモ

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のエラーログ取得関数

場合によってログに出力させたい値が異なる場合があったのでメモ。 function ...

MySQLで一連の処理を関数のように実行できるストアドプロシージャの設定と利用方法

MySQL関連のサイトを見ていた際にストアドプロシージャが云々というページがあっ ...

MySQLで歯抜けになっているint型の数値を取得する

MySQLで歯抜けになっているシーケンス番号を 取得したいケースがあった。 ■ソ ...

MySQLでオートインクリメントを使用せずにグループ毎に連番を設定する方法

MySQLでオートインクリメントを使用せずにグループ毎で連番を割り振りたかった。 ...

MySQLに保存したデータをJSON形式で取得する方法

MySQLに保存したデータをJSON形式で利用したいということがたまにある(Ja ...