まずSQL文にユーザ入力をパラメータとして取り込む際, "'" . $var . "'"
あるいは "'{$var}'"
のように書いてはいけません.SQLインジェクション攻撃に対して脆弱になります.プリペアドステートメントおよびプレースホルダを使いましょう.
また,クエリ発行のタイミングでエラーがあった場合例外をスローするように設定しておくべきです.false
やnull
になるだけでは不親切すぎますよね.
さらに,パスワードハッシュには標準の password_hash
関数を使うようにしましょう.暗号化ベクトルなしのSHA256だけではまだ安全性の面で不十分です.
POSTでパラメータを受け取り,結果をJSONとして返すAPI風に実装してみます.mysqli
は使いにくいので**PDO
**で書きます.よほどのことがない限り,初心者がmysqli
を触る理由はありません.
php
1<?php
2
3// デフォルトでは「text/html」なので「application/json」であるとして明示する
4// 文字コードにはUTF-8を指定する
5header('Content-Type: application/json; charset=UTF-8');
6
7try {
8
9 // $_POST['id'], $_POST['message'], $_POST['password'] を文字列として確実に受け取る
10 // 「$$var」は可変変数で,順番に $id, $message, $password となる
11 foreach (['id', 'message', 'password'] as $var) {
12 $$var = (string)filter_input(INPUT_POST, $var);
13 if ($$var === '') {
14 // どれか1つでも空だったら「400 Bad Request」として処理を中断する
15 throw new RuntimeException("Missing parameter: $var", 400);
16 }
17 }
18
19 // PHP5.5以降使える最も安全なパスワードハッシュ生成関数を使用する
20 $password = password_hash($password, PASSWORD_DEFAULT);
21
22 // 東京の現在時刻の文字列を生成
23 $created_at = (new DateTime('now Asia/Tokyo'))->foramt('Y-m-d H:i:s');
24
25 // mydbデータベースに接続 (失敗するとPDOExceptionがスローされて処理が中断される)
26 $pdo = new PDO(
27 'mysql:host=localhost;dbname=mydb;charset=utf8',
28 'dbuser',
29 'dbpassword'
30 );
31
32 // SQL実行時のエラーでもPDOExceptionがスローされて処理が中断されるようにする
33 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
34
35 // INSERT文のプリペアドステートメントを生成し,
36 // 「?」のプレースホルダ部分に順番に変数を当てはめて実行する
37 $stmt = $pdo->prepare("
38 INSERT INTO posts(id, message, password, created_at)
39 VALUES (?, ?, ?, ?)
40 ");
41 $stmt->execute([$id, $message, $password, $created_at]);
42
43 // 結果をJSONで表示
44 $message = 'success';
45 echo json_encode(compact('message'), JSON_UNESCAPED_UNICODE);
46
47} catch (PDOException $e) {
48
49 // PDOがエラーを検知したときはここに飛んで来る
50 http_response_code(500); // 「500 Internal Server Error」
51 $error = $e->getMessage();
52 echo json_encode(compact('error'), JSON_UNESCAPED_UNICODE);
53
54} catch (RuntimeException $e) {
55
56 // 手動で中断したときはここに飛んで来る
57 http_response_code($e->getCode());
58 $error = $e->getMessage();
59 echo json_encode(compact('error'), JSON_UNESCAPED_UNICODE);
60
61}