『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版とほとんど同じため)、サポートサイトでは掲載しているので参考にしてください。

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

『Webアプリケーション構築入門』の郵便番号検索でPostgreSQLを使う方法(Javaの場合)

追記:無料で使えるHeroku Postgres Devは、行数が1万行に制限されることが発表されたので、別の方法(例:SQLiteを組み込む)を検討した方がいいでしょう。

拙著『Webアプリケーション構築入門』では、開発プラットフォームとしてJavaとPHPを採用しており、ウェブアプリを実際に公開するときは、自前のサーバ(VPSを含む)を使える人にはJava・PHPの好きな方を、レンタルサーバを使う人にはPHPを使って貰うつもりで執筆していました。

最近、自前のサーバでもレンタルサーバでもない第3の選択肢としてのPaaSが普及してきており、その一部は無料で使えるようになっています。「サーバ管理技術」よりも「アプリケーション開発」に興味がある人にとっては、自前のサーバやレンタルサーバよりPaaSの方が便利でしょう。しかし、拙著はPaaSを意識した書き方にはなっていないので、そのあたりの情報をアフターサービスとして提供していきたいと考えている今日この頃です。

Javaを無料で使えるPaaSの一つにHerokuがあります。Javaが使えるレンタルサーバはあまりないので(私が知らないだけ?)、そういう意味でもHerokuは魅力的なのですが、無料で使えるデータベース管理システム(DBMS)が、拙著で採用しているMySQLではなくPostgreSQLだというのが、初心者には障害になるかもしれません。この障害を回避するために、拙著の第9章「ウェブアプリの実例」で作成する「郵便番号検索システム(Google MapsとのマッシュアップやAjaxによるリアルタイム検索を含む)」でPostgreSQLを使う方法を紹介しましょう。

まずPostgreSQLをインストールします。

sudo apt-get install postgresql

PostgreSQLの管理者postgresのパスワードを適当に設定します(例:pass)。

sudo passwd postgres
#ここでパスワードを入力

郵便番号辞書データベースを作ります。拙著9.1.1項のとおりにファイルをダウンロードして、次のコマンドで必要なデータだけを集めたCSVファイルを作ります。各コマンドの意味は「man gawk」などとして確認してください。

nkf -Lu -w ken_all.csv | gawk -F, -v OFS="," '{print $3,$7,$8,$9,"\"\"","\"\""}'  > /tmp/zip.csv
nkf -Lu -w jigyosyo.csv | gawk -F, -v OFS="," '{print $8,$4,$5,$6,$7,$3}' >> /tmp/zip.csv

管理者になって、データベースmydbを作ります。

su postgres
#ここでパスワードを入力

createdb mydb

MySQLのコマンド「mysql」に相当するコマンド「psql」を実行します。

psql mydb

テーブルを作成し、先に作成したCSVファイルをインポートします(拙著9.1.2項とは異なり、必要なデータだけをインポートすることにします)。

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
);

COPY zip FROM '/tmp/zip.csv' WITH CSV;

インデックスを作成します。

CREATE INDEX code_idx ON zip (code);

Webアプリから接続する際のパスワードを設定します。これは、先に設定したOSのパスワードと同じである必要はありません。

ALTER USER postgres WITH PASSWORD 'pass';

「\q」と入力してコマンドpsqlを終了します。

拙著8.2.2項「Javaからデータベースへのアクセス」の場合と同様に、「PostgreSQL JDBC ドライバ」を追加します。

コードの変更はzip.jsp(p. 134あるいはサポートページを参照)のデータベース接続部分だけです。次のように書き換えます。ここで使うパスワードは、先のALTER USER文で設定したパスワードです。

//データベースに接続(Heroku非対応)
Class.forName("org.postgresql.Driver").newInstance();
String url = "jdbc:postgresql://localhost/mydb";
Connection conn = DriverManager.getConnection(url, "postgres", "pass");

以上の準備で、拙著第9章の郵便番号検索システムはPostgreSQLで動くようになります。このままではまだHerokuでは動きませんが、とりあえず、ローカルで動くようになったので一区切りです。

オープンソースデータベース標準教科書 -PostgreSQL-などというものもありますね。

ブラジル・シンドローム(Google Maps)

メルトダウンと聞いて「何をいまさら」と思うのは、体制にとって都合のいい反応なのでしょう。

それはともかく、「メルトダウンした燃料がどんどん下に落ちていって、ついには地球の反対側つまりブラジルを汚染する」という話があって、ブラジルの人たちが逃げ惑っているそうです(嘘)。

地球儀を使えば、フクシマの反対側が陸地ではないことはわかるのですが、Google Mapsで確認しておきましょう。ブラジルでパニックや風評被害があってもいけませんし(WolframAlphaで確認する方法を先日紹介しました)。

Google Maps
フクシマの反対側は海

地球が完全な球では無いことは考慮していませんが、WolframAlphaの結果とだいたい同じなので、とりあえずよしとしましょう。

お約束ですが、Google Mapsを使ってオリジナルのウェブページをつくる方法は、拙著『Webアプリケーション構築入門』で紹介しています。

Mathematicaでやるのが一番簡単と思いつつ、Google Earthで確認する方法を後で書きます。(追記:書きました。

TwitterとGoogleマップ, Google翻訳

Twitearth

Twitterに流れ込み、はき出される膨大な情報を、エンドユーザ向けのエンタメに生かせないものか。Twitterのつぶやきには位置情報を付加できるのだが、今日現在、位置情報が付加されているつぶやきは、全体の0.5%程度しかない。特別な手続きなしにTwitterから取れるつぶやきの0.5%程度なら、地図上でリアルタイムに配置していくことができるだろう。ついでに、外国語が苦手な人向けに、すべてのつぶやきは日本語に訳しておこう。

厳密に言えば、翻訳先の言語はつねに日本語というわけではなく、ブラウザの言語設定にあわせている。たとえば、ブラウザの言語設定を英語にしているユーザが相手なら、すべてのつぶやきを英語に訳しておくのが親切だろう。

これはいわゆるマッシュアップというやつだが、使っているサービスは以下の通り。

適当なサーバがあれば、認証方法をOAuthに変えて公開する。

公開した:Twitearth この星のつぶやき

お約束ですが、こういう話を基本から学びたいという方には、拙著『Webアプリケーション構築入門 実践!Webページ制作からマッシュアップまで 』(森北出版, 2011)がおすすめです。