勉強したことのメモ

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でphpMyAdminやAdminer上だけ文字化けする場合の対応方法

レンタルサーバーのプログラムでWebページ上では文字化けしていないのに、phpM ...

MySQLにて直近のクエリで発行されたAUTO_INCREMENTの値を取得する方法

やりたかったことは「MySQLで新規登録(INSERT)なら、登録時のAUTO_ ...

MySQLでサイズの大きいファイルをインポートする際の注意点

MySQLでサイズの大きい(3GBほどの)dumpファイルを異なるサーバに移行し ...

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

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