『Webアプリケーション構築入門』の郵便番号検索システムをPHP Fog上で動かす方法


追記:PHP Fogは2012年12月にサービスを終了するそうなので、後継サービスであるAppFogを試しました。→『Webアプリケーション構築入門』の郵便番号検索システムをAppFog上で動かす方法

ウェブアプリ構築の入門書である拙著『Webアプリケーション構築入門 第2版』のゴールは、Google Mapsを活用する郵便番号検索システムです。サーバ・サイドのプログラミング言語はJavaとPHPのうち、好きな方を選んで読み進められるようになっています。

作成したウェブアプリを公開する方法は人によってさまざまでしょうが、PaaSの無料プランを使うのは魅力的な選択肢です。

Javaで作成したウェブアプリをHerokuというPaaSの上で動かす方法を以前紹介しました。(参照:『Webアプリケーション構築入門』のデータベースアプリケーションをHeroku上で動かす方法

ここでは、PHPで作成したウェブアプリをPHP FogというPaaSの上で動かす方法を紹介します。

手順は次のようになります(1と2は、PHP Fogを使い始めるときに1回だけやればOKです)。詳しくは、Jumpstartsあたりを参照してください。

  1. PHP Fogのアカウントを作る
  2. SSH鍵ファイルを登録する
  3. アプリを作る
  4. データベースを作る
  5. git clone URL
  6. アプリを作る
  7. git add .
  8. git commit -m 'コメント'
  9. git push

PHP FogではMySQLが使えますが、そのアクセス方法は、拙著で説明したのとは少し違っています。データベースへの接続情報は、環境変数に格納されているので、それを参照しながら接続します。参考までに、データベースに接続するためのコードを書くと、次のようになります。p. 149に掲載されているコードと比較してください。

//データベースに接続
$server = getenv('MYSQL_DB_HOST');
$username = getenv('MYSQL_USERNAME');
$password = getenv('MYSQL_PASSWORD');
$dbname=getenv('MYSQL_DB_NAME');

$db = new PDO("mysql:host=$server;dbname=$dbname", $username, $password,
                array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));

しかし、ここではこのコードは使いません。郵便番号データベースを構築するのが面倒だからです。拙著で紹介したように、テーブルを作成して郵便番号データのCSVファイルをインポートすれば郵便番号データベースを構築できるのですが、郵便番号データベースのためのCSVファイルは比較的大きいため、phpMyAdminでインポートしようとするとタイムアウトしてしまうのです。無料で利用できるデータベースサイズが5MBというのもいまいちです。Herokuのときもそうでしたが、無料の範囲内で遊ぼうとすると、データベース周りがいろいろ面倒です。

タイムアウトしてしまうという問題は、「split -C 500K /tmp/zip.csv」などとして分割し、「for f in x*; do mv $f $f.csv; done」として拡張子.csvを付けて、一つずつインポートすれば回避できますが、とても面倒です(Railsに行くのはここではがまんしましょう)。

こんなところで苦労するのはいやなので、Herokuの場合と同様に、SQLiteを組み込んで使うことにします。

ローカルでの実験のために、PHPからSQLiteを使えるようにしておきましょう。

sudo apt-get install php5-sqlite
sudo service apache2 restart

データベースファイル(mydb.sqlite)の作り方はHerokuの場合と同じなので省略します(完成したファイルはここにあります)。このファイルを、zips.phpと同じディレクトリに保存します(接続時にパスを指定するなら、別のディレクトリでもかまいません)。

zips.php内のデータベースに接続する部分を次のように修正します。

//データベースに接続
$db = new PDO('sqlite:mydb.sqlite');

Ajaxによって1文字入力するごとに検索結果を更新するようにしたものは、拙著の中では割愛しましたが(Java版とほとんど同じため)、サポートサイトでは掲載しているので参考にしてください。

実行結果は下のようになります。

SQLite for Java on Heroku


拙著『Webアプリケーション構築入門 第2版』は、ウェブアプリ構築の入門書です。サーバ・サイドプログラムは、JavaとPHPで作成しており、読者は自分の好きな方を選んで読み進められるようになっています。

PHPで作ったウェブアプリはレンタルサーバとかで簡単に公開できるけど、Javaで作ったウェブアプリはちょっと面倒でした。

しかし、HerokuならJavaが動くので、これを使えば簡単です。このことについて、かつて書きました。

しかし、確かにJavaは動きますが、データベース管理システムは拙著で採用したMySQLではなくPostgreSQLなので、PostgreSQLへの対応が必要です。このことについて、かつて書きました。

しかし、拙著のサンプルアプリである郵便番号検索システムのためのデータベースは比較的大きく、ウェブアプリをPostgreSQLに対応させただけでは、データのインポートが面倒で使えません。この問題は、Postgres dev planという無料のアドオンで解決するのが簡単です。このことについて、かつて書きました。

しかし、これだけ書いた後で、「Postgres dev planでは、1つのテーブルに1万行までしか入れられないようにする予定です」というアナウンスがありました。郵便番号データベースには、14万行以上のデータがあるので、Postgres dev planではダメになるわけです。

月9ドルのBasic planに移行すれば問題は解決するのですが、そんなものを学生に勧められるわけもなく、もう面倒くさいのでSQLiteを組み込んで使うことにします。さらばPostgreSQL。

必要な作業は3つです。

  1. データベースファイルの作成
  2. SQLiteのためのライブラリの導入
  3. データベースへの接続方法の修正

データベースファイルの作成

FirefoxのアドオンであるSQLite Managerを使うのが簡単です(それでも面倒な人のために、できあがったファイルをここで公開します)。

  • アドオンをインストールする
  • ツール→SQLite Manager
  • pom.xmlがあるのと同じディレクトリにmydb.sqliteを作成する
  • デーブルを作る
  • 郵便番号データをインポートする

テーブルは次のようなSQL文を実行して作成します。

CREATE TABLE zip (
  code CHAR(7) NOT NULL,
  address1 VARCHAR(10) DEFAULT '' NOT NULL,
  address2 TEXT NOT NULL,
  address3 TEXT NOT NULL,
  address4 TEXT NOT NULL,
  office TEXT NOT NULL
);

CREATE INDEX code_idx ON zip (code)

データのインポートには、以前作成した/tmp/zip.csvを使えばいいでしょう。

SQLiteのためのライブラリの導入

pom.xmlに、次のような要素を追記します。

<dependency>
  <groupId>org.xerial</groupId>
  <artifactId>sqlite-jdbc</artifactId>
  <version>3.7.2</version>
</dependency>

データベースへの接続方法の修正

zips.jspを次のように修正します。

//データベースに接続
Class.forName("org.sqlite.JDBC");
Connection conn=DriverManager.getConnection("jdbc:sqlite:mydb.sqlite");

あとは『Webアプリケーション構築入門』のウェブアプリをHeroku上で動かす方法と同じです。


動作例