サンプル・プログラムの実行例
サンプル・プログラム
insert.php | サンプル・プログラム |
解説:バリデーション
そこで、データベースに不正なデータを登録しないために、事前にバリデーションチェックを行う。
190: /**
191: * 数値のバリデーション
192: * @param mixed $data チェックする数値
193: * @param string $type int:整数 float:浮動小数
194: * @param mixed $min, $max 最小値、最大値
195: * @param string $errmsg エラーメッセージを格納する
196: * @return bool TRUE:成功/FALSE:失敗
197: */
198: function validNumber($data, $type, $min, $max, &$errmsg) {
199: $res = TRUE;
200: $errsg = '';
201:
202: //整数かどうか
203: if (preg_match("/int/i", $type) != 0) {
204: $flag_int = TRUE;
205: $format = "%d";
206: } else {
207: $flag_int = FALSE;
208: $format = "%f";
209: }
210:
211: //引数チェック
212: if ($min > $max) {
213: $errmsg = sprintf("最小値({$format})が最大値({$format})より大きい.", $min, $max);
214: $res = FALSE;
215:
216: //値の取り出し
217: } else {
218: if ($data == '' || $data == NULL) {
219: $errmsg = '値がない.';
220: $res = FALSE;
221: } else if (! is_numeric($data)) {
222: $errmsg = '数値ではない.';
223: $res = FALSE;
224: } else {
225: if ($flag_int) $data = round($data); //整数に丸める
226: //最大値・最小値チェック
227: if ($data > $max) {
228: $errmsg = sprintf("最大値({$format})より大きい.", $max);
229: $res = FALSE;
230: } else if ($data < $min) {
231: $errmsg = sprintf("最小値({$format})より小さい.", $min);
232: $res = FALSE;
233: }
234: }
235: }
236: return $res;
237: }
validNumber の仕組みは「PHPセキュリティ対策:正規化した数値を取り出す」で紹介した getValidNumber とほぼ同じである。
名前、業績といった文字列データに対しては、ユーザー関数 validString を使ってバリデーションを行う。データの存在可否、最大長、最小長、異常文字を含んでいるかどうかチェックする。
validString の仕組みは「PHPセキュリティ対策:正規化した文字列を取り出す」で紹介した validString とほぼ同じである。
解説:INSERT文
INSERT テーブル名 (カラムの並び) VALUE (登録データの並び)
解説:INSERT文の実行
327: /**
328: * INSERT実行
329: * @param object $pdo PDO
330: * @param array $items INSERTするデータ
331: * @param sring $errmsg エラーメッセージを格納
332: * @return string bool TRUE:成功/FALSE:失敗(重複データあり)
333: */
334: function insertItems($pdo, $items, &$errmsg) {
335: $msg = '';
336: $res = TRUE;
337: $patterns = array("/\p{Cc}/u"); //制御文字を除く
338:
339: //バリデーション
340: if (validString($items['name'], NAME_MIN, NAME_MAX, $patterns, $msg) == FALSE) {
341: $errmsg['name'] = '名前が' . $msg;
342: $res = FALSE;
343: }
344: if (validNumber($items['birth'], 'int', YEAR_MIN, YEAR_MAX, $msg) == FALSE) {
345: $errmsg['birth'] = '生年が' . $msg;
346: $res = FALSE;
347: }
348: if (validNumber($items['death'], 'int', YEAR_MIN, YEAR_MAX, $msg) == FALSE) {
349: $errmsg['death'] = '没年が' . $msg;
350: $res = FALSE;
351: }
352: if (validString($items['comment'], COMMENT_MIN, COMMENT_MAX, $patterns, $msg) == FALSE) {
353: $errmsg['comment'] = '業績が' . $msg;
354: $res = FALSE;
355: }
356: if ($res == FALSE) return $res;
357:
358: //重複チェック
359: $stmt = $pdo->prepare(PRE_COUNT);
360: $stmt->bindValue(':name', $items['name'], PDO::PARAM_STR);
361: $stmt->execute();
362: $res = $stmt->fetch();
363: if ($res[0] > 0) {
364: $errmsg['duplicate'] = '登録済みデータです.';
365: return FALSE;
366: }
367:
368: //INSERT実行
369: $stmt = $pdo->prepare(PRE_INSERT);
370: $stmt->bindValue(':name', $items['name'], PDO::PARAM_STR);
371: $stmt->bindValue(':birth', $items['birth'], PDO::PARAM_INT);
372: $stmt->bindValue(':death', $items['death'], PDO::PARAM_INT);
373: $stmt->bindValue(':comment', $items['comment'], PDO::PARAM_STR);
374:
375: return $stmt->execute();
376: }
前述のバリデーション関数を用いてデータのチェックをした後、すでに登録されたデータでないかどうか(重複する名前がないかどうか)をSELECT文を使って調べる。
すべてがクリアできたら、INSERT文を実行する。
参考サイト
- プリペアドステートメント:公式
- INSERT 文:DBOnline
- PHPセキュリティ対策:正規化した数値を取り出す:ぱふぅ家のホームページ
- PHPセキュリティ対策:正規化した文字列を取り出す:ぱふぅ家のホームページ
- PHP+SQLite:参考書籍の紹介:ぱふぅ家のホームページ
SQLの INSERT 文を書くことで、レコードを1つ追加する。