勉強したことのメモ

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のトリガーを使用して特定のテーブルの操作を行った際に別テーブルにログを残す方法

MySQLにトリガーという機能があるらしくどのようなものか調べたところ、事前に「 ...

MySQLで同一サーバーの異なるDB内のテーブルをJOINする

同一のMySQLサーバーでdb1データベースのtable1テーブルと、db2デー ...

adminerでMySQLに接続しようとするとエラーになる場合の対応方法

新しく構築したサーバにadminerを入れて接続しようとすると、「mysqlnd ...

PLESK利用時にMySQLでrootのパスワードが分からない場合の対応方法

pleskで管理しているサーバがあり、mysqlのrootのパスワードが分からな ...

MySQLでスレッドの実行状況を表示しスレッドの経過時間チェックや特定スレッドを強制終了する方法

データベースサーバが重たく、原因を調査する機会があった。サーバ自体のメモリやCP ...