PHPとMySQLを使った動的なWebページ

一般ユーザーからの投稿や管理上の更新を処理する動的なWebサイトを構築するために、PHPスクリプト言語とMySQLデータベースを初めて利用してみた。意外にも課題は簡単だった。

高望みはせずに、似かよった3つのページ(”What’s New”、”Events”、”Sports Broadcasts”)を学生が(ほぼ全面的に)運営する学内ラジオ局WGAJのサイトに作ることを目標とした。必要なものは、簡単なデータベース、上記の3ページに必要な情報を保存する機能、そして投稿の追加や削除を行える管理用のページだ。サイトのトラフィックは少ないので、速度とスケーラビリティを考慮する必要はないが、予算と単純性はおろそかにできない。開発を外部に発注することはできないし、すでに年間の活動予算は底を尽こうとしていた。

まず、PHPとMySQLについて書かれたものを読むことから始めた。PHPサイトは、PHP言語の要約とチュートリアルが揃っていて、機能を調べるにはもってこいだ。MySQLサイトも、SQL言語を学ぶ貴重な情報源である。

インストール

最初のステップは、ソフトウェアのインストールだ。Debianを使っていたが、apt-getは使わずにソースからインストールすることにした。設定は難しくなるが、成功の確率はより高い。www.php.netから、PHP 4.3.2のソースtarballをダウンロードした。次に、www.mysql.comにアクセスし、少し前のバージョン3.23のバイナリをダウンロードした(下までスクロールしてソースツリー全体を調べることはやらなかった)。

意気込んで、まずPHPをコンパイルしてみた。PHPのタグ形式<? … ?>と若干の基本コマンドは知っていたので、さっそくtest.phpページを作成して試してみたが、何も起こらない。Googleで検索し、IRCでアドバイスを求めた結果、PHPをApacheに統合するにはapxsというものをインストールの./configure時にリンクする必要があるとわかった。ざっとapt-cache searchを実行したところ、この謎めいたapxsはApache開発パッケージに含まれていると判明。パッケージをダウンロードし、updatedblocate apxsを実行すると、apxsは/usr/binに姿を現した。–with-apxs=/usr/bin/apxsを実行してコンパイルした後で、/etc/apache/httpd.confを開いて、次の設定を追加した。

AddType application/x-httpd-php .php .phtml
AddType application/x-httpd-php-source .phps

その後でApacheデーモンを再起動し、test.phpページをもう一度試す。今度は成功!

次にMySQLを動かすために、パッケージを解凍してフォルダに移動してから、最初に頭に浮かんだ論理的なことを、つまり./configureを実行してみた。テキストが画面に吐き出され、プログラムはコンパイル前のバージョンだが、それでも起動されるという意味のことが告げられた。その後に表示された暗号のようなエラーメッセージからは、設定が予定どおりに進まなかったことがかろうじて読み取れた。やれやれと思い、マニュアルを読むことにした。インストール・マニュアルを開き、そこに書かれたことを実行し、もう一度./configureを試してみた。今回はエラーメッセージは表示されず、ただ”030725 02:30:14 mysqld ended.”というメッセージが出た。しばらく探した結果、エラーログをデータディレクトリに発見。そこには、ポート3306に接続できなかったことが記されていた。IRCでこの件について質問してみると、コマンドfuser -v 3306/tcpを実行してみてはどうかという貴重なアドバイスをもらった。このコマンドで、最初に試したときからmysqld(MySQLデーモン)は動作していたが、何もしなかったことがわかった。プロセスの山をかき分けたあげく、推奨される./bin/safe_mysqlコマンドをようやく正常に実行することができた。

(IRCは助言を乞うにはよい場所で、irc.freenode.netのIRCチャネル#mysqlと#phpは特に助けになったが、忍耐を強いられることもある)

すぐにわかったのは、PHPをもう一度コンパイルしなければならないことだ。今回は、PHPをmysqlにリンクするために、オプション–with-mysql=/usr/local/mysqlを使う必要がある。教訓:MySQLを最初にインストールすること。

データベース

次のステップは、データベースの作成だ。おそらく作業の一番簡単な部分だろう。チュートリアルを軽く読んだ後で、mysqladmin -uroot create wgaj_dbを実行してデータベースを作成し(WGAJは局のコールサイン)、mysqlconnect wgaj_dbを実行してデータベースを開き、編集した。

テーブルを作成するには、何をそこに保存するかを決める必要がある(テーブルの削除と再作成を5、6回繰り返して、ようやくそれが身に染みた)。簡単な投稿を保存するテーブルは、ほかの2つより単純だ。投稿の本文を保存できる大きさの領域とそれより小さい署名用の領域があればいい。最初は、テキストを文字として扱おうとtext char(1024)を使ってみた。しかし、charデータ型で扱える情報は最大255バイト。これでは足りない。だが、テキストデータ型を使えばchar型よりも多くの情報を保存できることがわかった。こうして、あまり苦労しないで最初のデータベースを作成できた。このテーブルを構成するのは、参照用の整数キー、テキストブロック、署名用のchar(255)である。残りの2つのテーブル(Eventsページ用とSportsページ用)も、変数が2つ多いだけで、これまた簡単に作成できた。

PHP

Cスタイルの言語のコーディング経験があるなら、PHPは朝飯前だ。なかったとしても朝飯前である。PHPをHTMLに統合するのは簡単だし、MySQL呼び出しは論理的で処理の流れを追いやすい。PHPページは.phpファイルタイプのHTMLページのようなものだ。PHPのコードは<? … ?>タグの内部に書く。echoコマンドを使えば、HTMLタグとテキストをPHPに送り込むことができる。ただし、PHPの真価はMySQLデータベースを扱えることにある。

データベースに接続してテーブルを読み取るには、次の簡単なコードをPHPファイルに追加する。

$db = mysql_connect("server", "user", "password");
mysql_select_db("database_name", $db);
$query = mysql_query("SELECT * FROM table_name", $db);
while ($tablerow = mysql_fetch_array($query)) { ..... }

whileループのコードは、テーブルのすべての行に対して実行される。テーブル変数には、配列$tablerow[‘var_name‘]を使ってアクセスが可能だ。

HTMLフォームの統合もこれと同じように簡単だ。update.phpというページにフォームがあり、そのaction属性にupdate.phpが設定されている場合に、ユーザーがフォームを送信すると、フォームは最新の状態に更新され、各項目の値が配列$_POST[]に格納される。この配列にアクセスするコードは、$_POST[‘name_of_form_item‘]だ。

ひと工夫

立ち往生したのは、そのすぐ後だった。イベント予定をページに表示したいので、日程の近い順にイベントを掲載する必要がある。データベースにはYYYYMMDD形式の8桁の整数で日付を保存することにしたので、この数字でソートすれば日付順になるはずだ。問題は、整数を表示可能な日付に変換する処理だった。最初、日付の整数を100で割った余りが日の数字となると考えた。この方法の問題点は2つ。まず、効率が悪い。そして、PHPのWebサイトを見る限り、PHPには剰余演算の機能がない[訳注:%演算子で可能]。自分で作るつもりもない。

次に思いついたのは、8桁の日付を文字列として扱い、これをパーツに分解することだった。比較的早く簡単に処理できるはずだ。PHPはPerlと同じでデータ型を持たないので、日付コードを文字列に明示的に変換する必要はない。PHPのデータにはスカラと配列の違いしかない。PHPの機能一覧をもう一度チェックし、Javaのsubstringメソッドか、RealBasicのleft関数やright関数(文字列の左または右からX個の文字を取り出す機能)に近いものを探した。しかし、今回も適当なものは見つからなかった[訳注:substr関数で可能]。

ただし、chunk_split(X,Y,Z)関数(文字Zを文字列X内にY文字ごとに挿入する)とsplit(X,Y)関数(文字Xが現れるたびに文字列Yから小さな文字列を切り出す)があった。2つの関数を組み合わせると、こんな芸当ができる。chunk_split関数を使って整数の途中に空白を挿入し、split関数とlist関数(これも単純な関数)を使って空白を境に2つの文字列に分離するのだ。

$temp = chunk_split($mysql_row['date'], 4, " ");
list($year, $monthday) = split($temp, " ");

これと同じ処理を$monthdayにも実行すると、自由にフォーマットできる3つの変数ができあがる。データをページに表示するコマンドは、echo $month . ” ” . $day . “, “$year;だ(PHPではドット記号で文字列を連結する)。

今思うと、もっと単純で手早く効率的な方法もあったのは確かだが、汚いコードにはならずに済んでいる。WGAJサイトは次の年度が始まるまで実際の運用を再開しないが、これまでのところWGAJの責任者はご満悦だ。

動的ページを作りたいが大げさになりそうでためらっているなら、心配は無用。MySQLとPHPの立ち上げに時間はいらないし、フリーで利用できる(OSS万歳!)。使用法は覚えやすく、やりたいことは何だってできる。

Sean Mortonは、Deerfield Academyに在学中。