リスト項目の追加
リスト1には、form.php(リスト3を参照)へのリンクも含まれています。これは、HTMLフォームを使用して新しい作業項目をデータベースに追加するスクリプトです。
一見したところ、このリスト3は、図2の画面(項目の説明を示すテキストフィールドと実施期限および優先度のドロップダウンリストを含んだ画面)を作成するための単純なフォームです。しかし、このフォームは後でもっと複雑になってくるので、現時点ではこのくらい単純なものにしておきます。
<?php require 'include.php'; // get current year $year = date('Y'); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> <head> <title>To-Do Form</title> <link rel="stylesheet" href="main.css" /> </head> <body> <h2>Enter To-Do Item</h2> <form method="post" action="save.php"> <table> <tr> <td><label>Title:</label></td> <td><input type="text" name="name" class="txt" value=""></td> </tr> <tr> <td><label>Due Date:</label></td> <td> <select name="due_dd" class="txt"> <?php for ($x=1; $x<=31; $x++) { ?> <option value="<?php echo $x; ?>"> <?php echo $x; ?></option> <?php } ?> </select> <select name="due_mm" class="txt"> <?php for ($x=1; $x<=12; $x++) { ?> <option value="<?php echo $x; ?>"> <?php echo $months[$x]; ?></option> <?php } ?> </select> <select name="due_yy" class="txt"> <?php for ($x=$year; $x<=($year+5); $x++) { ?> <option value="<?php echo $x; ?>"> <?php echo $x; ?></option> <?php } ?> </select> </td> </tr> <tr> <td><label>Priority:</label></td> <td> <select name="priority" class="txt"> <?php for ($x=1; $x<=5; $x++) { ?> <option value="<?php echo $x; ?>"> <?php echo $priorities[$x]; ?></option> <?php } ?> </select> </td> </tr> </table> <p><input type="submit" name="submit" value="Submit" class="btn"></p> </form> </body> </html>
ユーザーがこのフォームを送信すると、save.php(リスト4を参照)が呼び出されます。このスクリプトは、ユーザー入力を検証し、それをデータベースに保存するために必要なSQLを生成するという重要な処理を行います。
リスト1ではSELECTクエリを使ってSQLiteデータベースからレコードを取得する方法を示しましたが、リスト4ではデータベースに新しいレコードを追加する方法を示しています。リスト4の前半部分ではもっぱらユーザー入力の検証を行っています。ここでは、正規表現を使ってnameフィールドに不正な文字が含まれていないかを確認し、さらにcheckdate()関数を使って実施期限が有効な日付であるかどうかを確認します。
入力が有効な場合には、リスト1と同じ方法で新しいPDOインスタンスを初期化し、PDOのquote()メソッドを使ってフォームの送信データ中の特殊文字をエスケープします。その後、これらの値をSQLのINSERTクエリ文字列に組み込みます。最後に、PDOのexec()メソッドを使ってクエリを実行し、レコードをデータベースに保存します。exec()メソッドは、そのクエリの結果として変更された行の数を返します。クエリが完了したら、PDOインスタンスを破棄し、クライアントブラウザをインデックスページ(リスト1を参照)にリダイレクトします。
<?php if (isset($_POST['submit'])) { // perform input validation // add errors to $errors array $errors = array(); // check name $name = stripslashes($_POST['name']); if(!isset($_POST['name']) || !preg_match( "/^[a-z0-9][a-z0-9\\'\\.[:space:]]+$/i", $name)) { $errors[] = 'Invalid title'; } // check priority if (!isset($_POST['priority']) || !is_numeric($_POST['priority'])) { $errors[] = 'Invalid priority'; } // check date validity if (!checkdate($_POST['due_mm'], $_POST['due_dd'], $_POST['due_yy'])) { $errors[] = 'Invalid date'; } // print errors and exit // if no errors, proceed to save the record to the database if (sizeof($errors) > 0) { die('Error: <br/>' . implode($errors, '<br/>')); } else { try { // connect to database $dbh = new PDO('sqlite:../../db/todo.db3'); $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); // quote all input characters $name = $dbh->quote($name); $priority = (int) $_POST['priority']; // generate UNIX timestamp for due date $due = $dbh->quote(mktime( 0,0,0,$_POST['due_mm'], $_POST['due_dd'],$_POST['due_yy'])); // generate INSERT query $sql = "INSERT INTO items ( name, due, priority, status) VALUES ($name, $due, '$priority', '1')"; // execute query $dbh->exec($sql); unset($dbh); // redirect to index page header('Location: index.php'); exit(); } catch (PDOException $e) { die('Error: ' . $e->getMessage()); } } } else { die('Error in form submission'); } ?>
