SHOEISHA iD

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

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

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

japan.internet.com翻訳記事

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

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

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

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

 ここまでの段階で、PHP Webアプリケーションから軽量のSQLiteデータベースに対してSELECT、INSERT、UPDATEクエリを実行できるようになりました。あと必要なのは、DELETEコマンドでレコードを削除する機能と、UPDATEコマンドでレコードを完了済みとしてマークする機能です。

 どちらの機能も、実装は特に難しくありません。項目を完了済みとしてマークするには、項目のstatusフィールドを1(保留)から0(完了)に変更します。この処理はdone.phpで行います。

<?php
// check for record ID
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
    $id = (int) $_GET['id'];
    try {
        // connect to database
        $dbh = new PDO('sqlite:../../db/todo.db3');
        
        // update item record
        // change status field
        $now = mktime();
        $dbh->exec("UPDATE items SET status = '0', 
           complete = '$now' WHERE id = '$id'");
        
        // redirect to index page
        header('Location: index.php');
        exit();
    } catch (PDOException $e) {
       die('Error: ' . $e->getMessage());
    }    
} else {
    die('Error in form submission');    
}
?>

 このスクリプトでは、UPDATEクエリを使用して、選択したレコードのstatusフィールドを0に変更します(クエリの実行にはやはりPDOのexec()メソッドを使用します)。また、現在の日付(完了日)をUNIXタイムスタンプ形式で保存していることに注意してください。

 項目を削除するには、対象項目のレコードIDを使用してDELETEクエリを発行します。この処理はdelete.phpで行います。

<?php
// check for record ID
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
    $id = (int) $_GET['id'];
    try {
        // connect to database
        $dbh = new PDO('sqlite:../../db/todo.db3');
        
        // delete item
        $dbh->exec("DELETE FROM items WHERE id = '$id'");
        
        // redirect to index page
        header('Location: index.php');
        exit();
    } catch (PDOException $e) {
       die('Error: ' . $e->getMessage());
    }    
} else {
    die('Error in form submission');    
}
?>

 この時点で、今度はアプリケーションのインデックスページを修正し、各レコードの隣に新しい機能のリンクを追加する必要があります。修正版のインデックスページはリスト7のようになります。

 この変更により、すべての保留項目に「Mark as Done」、「Change」、「Remove」というリンクが表示され、すべての完了項目に「Remove」リンクが表示されるようになります。さらに、修正版スクリプトではもう1つ機能を追加し、現在の日付(保留項目の場合)または完了日(完了項目の場合)を項目の実施期限と比較して、期限を過ぎている項目を赤で表示するようにしています。前掲の図1は、上記すべての機能を実装した状態のインデックスページです。

リスト7 修正版のindex.php
<?php
require 'include.php';
try {
    // connect to database
    $dbh = new PDO('sqlite:../../db/todo.db3');
    
    // query and retrieve pending items
    $sth = $dbh->query("SELECT * FROM items WHERE status = '1' 
       ORDER BY due DESC, priority DESC");
    $pending = $sth->fetchAll();
    $sth = null;
    
    // query and retrieve completed items
    $sth = $dbh->query("SELECT * FROM items WHERE status = '0' 
       ORDER BY due DESC, priority DESC");
    $complete = $sth->fetchAll();
    unset($dbh);
} catch (PDOException $e) {
   die('Error: ' . $e->getMessage());
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
  <title>To-Do List</title>
  <link rel="stylesheet" href="main.css" />
</head>

<body>
  <h2>To-Do List</h2>
  <div class="category">Pending Items</div>
  
  <!-- generate listing of pending items -->    
  <?php if (sizeof($pending) > 0) {  ?>
  
  <table>
    <tr>
      <td class="head"></td>
      <td class="head">Due date</td>
      <td class="head">Priority</td>
      <td></td>
      <td></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="done.php?id=
         <?php echo (int) $p['id']; ?>">Mark as done</a> | </td>
      <td><a href="form.php?id=
        <?php echo (int) $p['id']; ?>">Change</a> | </td>
      <td><a href="delete.php?id=
         <?php echo (int) $p['id']; ?>">Remove</a></td>
    </tr>
    
  <?php } ?>
  
  </table>
  
  <?php } else { ?>
    <p>None</p>
  <?php } ?>
  
  <!-- link to add a new to-do item -->    
  <p><a href="form.php">Add a new entry</a></p>
  
  <!-- generate listing of completed items -->    
  <div class="category">Completed Items</div>
  
  <?php if (sizeof($complete) > 0) {  ?>
  
  <table>
    <tr>
      <td class="head"></td>
      <td class="head">Due date</td>
      <td class="head">Completion date</td>
      <td></td>
    </tr>
    
  <?php foreach ($complete as $c) { 
    $class = ($c['complete'] > $c['due']) ? 'late' : 'ontime';
  ?>
  
    <tr>
      <td class="<?php echo $class; ?>">
         <?php echo $c['name']; ?></td>
      <td class="<?php echo $class; ?>">
         <?php echo date('d M Y', $c['due']); ?></td>
      <td class="<?php echo $class; ?>">
         <?php echo date('d M Y', $c['complete']); ?></td>
      <td><a href="delete.php?id=
         <?php echo (int) $c['id']; ?>">Remove</a></td>
    </tr>
    
  <?php } ?>
  
  </table>
  
  <?php } else { ?>
    <p>None</p>
  <?php } ?>
  
  
</body>
</html>

データベースのバックアップと復元

 これで作業リストアプリケーションは完成です。このアプリケーションを使用して作業項目を保存し、優先順位を指定または変更し、完了済みとしてマークし、完了した項目を削除することができます。しかし本稿を終える前に、このアプリケーションを運用するうえで重要な意味を持つ機能について触れておきたいと思います。その機能とはデータベースのバックアップです。

 SQLiteデータベースをバックアップするのは簡単です。このデータベースは1つのディスクファイルに格納されているからです。最も簡単なバックアップ方法は、このディスクファイルをバックアップメディアにコピーして、安全な場所に保管することです。しかしその他に、SQLiteの組み込みの.dumpコマンドを使用するという方法もあります。このコマンドを実行すると、対象データベースを一から再生成するのに必要なCREATE TABLEコマンドとINSERTコマンドを含んだファイルを生成できます。.dumpコマンドを単独で実行した場合の結果は次のとおりです。

sqlite> .dump
BEGIN TRANSACTION;
CREATE TABLE items (
  id integer not null primary key,
  name text not null,
  due integer not null,
  complete integer null,
  priority integer not null,
  status integer not null
);
INSERT INTO "items" VALUES(1,
  'Buy anniversary present',1184437800,NULL,4,1);
INSERT INTO "items" VALUES(2,
  'Send invoices',1180549800,NULL,5,1);
INSERT INTO "items" VALUES(3,
  'Finish homework',1180549800,NULL,1,0);
INSERT INTO "items" VALUES(4,
  'Visit Jane',1180290600,NULL,2,1);
INSERT INTO "items" VALUES(5,
  'Finalize hotel reservations',1181737000,NULL,5,1);
INSERT INTO "items" VALUES(6,
  'Angie''s birthday',1182537000,NULL,4,1);
INSERT INTO "items" VALUES(7,
  'Weed the lawn',1182237000,NULL,1,1);
COMMIT;

 このようにダンプ結果を画面に出力してもあまり意味がないので、ダンプ結果をファイルに出力するようにします。そのためには、.dumpコマンドの前に、.outputコマンドにファイル名を指定して実行します。

sqlite> .output todo.sql
sqlite> .dump
sqlite> .output stdout

 このバックアップファイルからデータベースを復元することは簡単にできます。SQLiteの.readコマンドにバックアップファイルの名前を渡して実行すればよいのです。これにより、ファイル内のSQLが自動的に読み込まれて実行され、データベースが再作成されます。

sqlite> .read todo.sql

 ここまで見てきたように、軽量データベースはWebアプリケーションで十分に利用できる段階まで来ており、各種のプラットフォーム、言語、機能セットをサポートする軽量データベースも登場しています。今度、データベース機能が必要だが大規模なデータベースを導入するほどのコストやリソースはないという状況に遭遇したら、ぜひ本稿で紹介したいずれかの軽量データベースを試してみてください。

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

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
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」など、さまざまなカンファレンスを企画・運営しています。

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

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

メールバックナンバー