SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

SQLiteとPHPで軽快なWebアプリケーションを作る

軽量データベースで作成するWebアプリケーション

ダウンロード サンプルソース (5.1 KB)

リスト項目の編集

 リスト3およびリスト4で示したフォームとフォーム処理コードに少し手を加えれば、既存レコードの編集機能を実現できます。

 しかしその前に、インデックスページを少し手直しして、各レコードの横に「Change」リンクを追加しましょう。そのためには、保留項目の表を作成するときに、「Change」リンクを含んだ<td>タグを新たに追加します。このリンクには、各項目のIDを含んだURLをリンク先として指定する必要があります。次のコードリストでは、この部分に関係するコードを太字で示しています。

...
  <table>
    <tr>
      <td class="head"></td>
      <td class="head">Due date</td>
      <td class="head">Priority</td>
      <td></td>
    </tr>
       
  <?php foreach ($pending as $p) {
    $class = (mktime() > $p['due']) ? 'late' : 'ontime';
  ?>
    <tr>
      <td class="<?php echo $class; ?>">
        <?php echo $p['name']; ?></td>
      <td class="<?php echo $class; ?>">
        <?php echo date('d M Y', $p['due']); ?></td>
      <td class="<?php echo $class; ?>">
        <?php echo $priorities[$p['priority']]; ?></td>
      <td><a href="form.php?id=
        <?php echo (int) $p['id']; ?>">Change</a></td>
    </tr>
       
  <?php } ?>
     
  </table>
... 

 次に、form.phpを修正して、レコードIDを指定してこのスクリプトを呼び出したときに、対応するレコードがデータベースから自動的に取得され、フォームに埋め込まれるようにします。修正版のフォームはリスト5のようになります。

 リスト5の第一の変更点は、スクリプトの最初の部分にさまざまなPDO呼び出しを追加していることです。このスクリプトは、レコードIDを指定して呼び出されると、新しいPDO接続を初期化し、SELECTクエリを使用して、該当レコードをフィールド-値のペアの配列という形で取得します。この部分では、dueフィールドのUNIXタイムスタンプ値を日、月、年の数値に分けるという処理も行っています。

 さらに、フォーム部分のさまざまな入力フィールドのコードにも手を加え、query()およびfetch()で生成したレコードセット配列から適切な値を取得してフォームに埋め込むようにしています。入力フィールドがドロップダウンリストの場合は、条件テストを使用して、あらかじめ適切なオプションが自動的に選択されるようにします。またこの修正版スクリプトでは、取得するレコードのIDを格納するためのidという隠しフィールドを追加しています(このフィールドはリスト6で使われます)。

リスト5 修正版のform.php
<?php
require 'include.php';
// get current year
$year = date('Y');
$record = null;
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
    $id = (int) $_GET['id'];
    try {
        // connect to database
        $dbh = new PDO('sqlite:../../db/todo.db3');
        
        // retrieve item record
        $sth = $dbh->query("SELECT * FROM items WHERE id = '$id'");
        $record = $sth->fetch();
        
        // break due date timestamp into constituent parts
        $date = getdate($record['due']);
        $record['due_mm'] = $date['mon'];
        $record['due_yy'] = $date['year'];
        $record['due_dd'] = $date['mday'];        
        unset($dbh);        
    } catch (PDOException $e) {
       die('Error: ' . $e->getMessage());
    }            
}        
?>
<!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="
           <?php echo $record['name']; ?>"></td>
      </tr>

      <tr>
        <td><label>Due Date:</label></td>
        <td>
          <select name="due_dd" class="txt">
          
          <?php for ($x=1; $x<=31; $x++) { 
            $selected = ($record['due_dd'] == $x) ? 'selected' : '';    
          ?>                
            <option value="<?php echo $x; ?>" 
              <?php echo $selected; ?>><?php echo $x; ?></option>
          <?php } ?>
          
          </select>
          
          <select name="due_mm" class="txt">
          
          <?php for ($x=1; $x<=12; $x++) { 
            $selected = ($record['due_mm'] == $x) ? 'selected' : '';    
          ?>                
            <option value="<?php echo $x; ?>" 
              <?php echo $selected; ?>><?php echo $months[$x]; ?>
            </option>
          <?php } ?>
          
          </select>
          
          <select name="due_yy" class="txt">
          
          <?php for ($x=$year; $x<=($year+5); $x++) { 
              $selected = ($record['due_yy'] == $x) ? 'selected' : '';
           ?>                
            <option value="<?php echo $x; ?>" 
              <?php echo $selected; ?>><?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++) {
             $selected = ($record['priority'] == $x) ? 'selected' : '';
          ?>                
            <option value="<?php echo $x; ?>" 
              <?php echo $selected; ?>>
              <?php echo $priorities[$x]; ?></option>
          <?php } ?>
          
          </select>
        </td>
      </tr>
    </table>
    
    <input type="hidden" name="id" 
           value="<?php echo $record['id']; ?>">    
    
    <p>
      <input type="submit" name="submit" value="Submit" class="btn">
    </p>
  </form>
</body>
</html>

 form.phpに上記の変更を加えたことにより、save.phpスクリプトにも変更の必要性が出てきます。ユーザーからフォームが送信されたときに、送信されたデータが既存レコードのものなのか新規レコードなのかを判断し、状況に応じて適切なUPDATEクエリまたはINSERTクエリを生成しなければならないのです。そこで、save.phpにも変更を加えます。修正版のsave.phpはリスト6のようになります。

 リスト6の変更点はそれほど多くありません。修正版スクリプトでは、idという隠しフィールドをフラグとして利用し、UPDATEクエリとINSERTクエリのどちらを生成するかを判断しています。PDOのexec()メソッドを前述のように使用して、データベースに対してクエリを実行します。

リスト6 修正版のsave.php
<?php
if (isset($_POST['submit'])) {
    
    // check if record ID exists in the form submission
    if (isset($_POST['id']) && is_numeric(trim($_POST['id']))) {
        $id = (int) $_POST['id'];
    }
         
    // 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 UPDATE or INSERT query
            if (isset($id)) {
                $sql = "UPDATE items SET name=$name, 
                  due=$due, priority='$priority',status='1' 
                  WHERE id='$id'";
            } else {
                $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');    
}
?>

次のページ
リスト項目のマーキングと削除

この記事は参考になりましたか?

japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Vikram Vaswani(Vikram Vaswani)

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/1607 2007/08/22 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー