phpプログラミング2

前回のphpプログラミングの続きを書こうとして題材を探していました。動的にWebを表示するには、ユーザーからの入力を受けて処理結果を表示するタイプと、何も要求がなくてその都度自動計算して表示するというものがあります。

type-a

type-b

前者は何を入力されるかがわからないので、入力された文字列の処理が大変面倒です。文字列の長さや数値の範囲などが想定の範囲内であるかないかなど、いろんな妥当性検査が必要です。また、悪意のあるスクリプトを書き込まれる可能性があるので、それらを排除することが必要です。こんなことは、簡単なphpプログラミングの紹介にはあまりふさわしくないので、後者の方式で何かいい事例がないかなぁと探していました。そんなときYouTubeでこんなのが流れてました。

いつ削除されるかわからないので、要点だけを書き起こしてみます。

明石家さんま:こちら、バックスペースからいただきました。「前略。ヤン土のみなさんこんばんは。道重さんがモーニング娘。に加入してから、2013年10月12日で3,919日となります。モーニング娘。在籍日数が歴代最長になりました。」えっ?
小川麻琴(ゲスト):すごぉい!
道重さゆみ:やったぁ!
小川麻琴(ゲスト):すごぉいねぇ。
明石家さんま:あっ、そうなの?「モーニング娘。が大好きで、歌に音程があることも知らず、オーディションに合格した中学校1年生の少女が24歳の女性になるまで10年10ヶ月をモーニング娘。として過ごしているんですね。」
道重さゆみ:はい。
明石家さんま:「道重さん在籍期間一位になった感想や、これからの抱負を聞かせて下さい。」ということですけど。誰が一位だったの、今までは?
道重さゆみ:今までは新垣里沙ちゃんが・・・。
明石家さんま:あっ、そうかそうかそうか。
・・・・・・・

そこで、最初は道重さゆみだけの年齢・在籍期間・在籍日数をリアルタイムに計算して表示するプログラムを作ろうと思ったのですが、どうせならモーニング娘。新旧全メンバーを対象にすることにしました。

その結果がこれです。

データベースの準備

htmlもそうですが、phpの場合はまずローカルでバグフィックスを充分に行ってからサーバーに上げるようにします。そうしないと、無限ループになって、サーバー側に思わぬ迷惑をかけることとなり、場合によってはアカウントの停止や契約解除となることもあり得ますから、要注意です。

データベースはMySQLを使いますが、phpMyAdminを使って以下のようなテーブルを作ります。通常リレーショナル・データベースの設計では正規化をしていくつかのテーブルに分けますが、今回の物は単純にひとつのテーブルだけで間に合います。テーブル名はmorningmusumeとします。

次に、MicrosoftExcelで表を作成し、各メンバーの情報を記入します。基本情報はWikipediaから得ました。旧メンバーは在籍日数等は変わることが無いので計算しないで済むように書き入れておきます。現役メンバーはゼロにしておき、その都度計算して表示することにします。

それからCSV形式に落とし、先頭のカラム行を削除します。文字コードをUTF-8に変換して、MySQLのテーブルに一括で書き込みます。その後、このテーブルはメンバーの追加がある程度で、常時変更する事は無いので、更新プログラムは作りません。phpMyAdminでまかないます。

UTF-8に変換

実際にはこのMySQLテーブルもローカルで作成し、全体のテスト完了後にSQL形式でバックアップをつくり、それをサーバー側で復元するという方式をとります。

ソースファイル

このプログラムの主要なソースはここからダウンロードできます。

解凍すると以下のようなファイルが入っています。拡張子はphpですが、中身は文字コードがUTF-8のテキストファイルです。テキストエディタ(メモ帳でも可)で印刷するとわかりやすいと思います。

+phpSource
  +controllers
    musume.php プログラムの本体部分
  +models
    musume_model.php データベースアクセスや関数の記述
  +views
    fotter.php テンプレートに読み込まれる、他のアプリケーションと共通のフッター部分
    header.php テンプレートに読み込まれる、他のアプリケーションと共通のヘッダー部分
    musume.main.php テンプレートに読み込まれる、実際に変更されるコンテンツ部分
    musume_tmpl.php 表示ページ全体を組み立てるテンプレート

コントローラー:musume.php

function Musume()は最初に実行されるところで、いわゆる初期処理です。今回のアプリケーションではセッション処理などはおこなわないので、とても単純です。URLヘルパーを使うので読み込んでいます。また、データベースアクセスや関数を記述しているモデルを読み込みます。

function index()が本体部分です。ソースのコメントに書いていますように、全メンバーのデータを読み出して配列に格納します。次に、写真をランダムに表示させる為にファイル名をモデル内の関数で生成させます。そしてhtmlのコンテンツ部分を作り、テンプレートにヘッダー、フッターとともに読み込ませて表示させます。

モデル:musume_model.php

モデル内ではデータベースアクセスや関数を記述します。データベースアクセスとしては、通常は追加・更新・削除がつきものですが、今回のアプリケーションではテーブル全体を一気に読み出すだけです。このとき、junという横出し順番を指定している項目の順に読み出しています。レコードはidによってユニークにキーが決められていますが、在籍日数順に表示したいので、こういう手法にしてます。時間の経過によって現役メンバーが旧メンバーを追い越した場合は手作業でjunの値を変更します。なんとも原始的ですね。

現在のところ、sayumi101.jpgからsayumi152.jpgまで52枚の画像を用意しています。この中からランダムに表示させる為に、数字の部分を乱数で決めています。

年齢計算と年月計算は中身はまったく同じもので、最後の歳と年が違うだけです。

日数計算は、秒で計算してから日になおすという手法です。phpにはこういう関数が準備されているので助かります。

ビュー:musume_tmpl.php、musume_main.php

header.phpとfooter.phpは他で使っているものをそのまま使っています。

テンプレートのmusume_tmpl.phpも基本的には他のものと同じですが、サイドのメニュー部分が必要無いので、スタイルシートも自己紹介のページなどと同じno_side.cssを使っています。

そして、musume.main.phpが肝心のコンテンツ部分です。

いきなり先頭に道重さゆみの写真をランダムに表示させてビジュアルにしています。文字だけでは面白くありませんからね。

各メンバーのレコード情報から年齢、在籍期間、在籍日数を計算して表示します。

卒業・脱退日の項目では、ゼロでない場合はその日付を、ゼロの場合は「現役」と表示させます。

在籍期間と在籍日数の項目では、旧メンバーの場合レコード内に記入されているものを、現役の場合は当日の日付で計算させます。

おまけとして「ラジオ番組」の継続期間も載せることにしました。モデル内の関数をコールするときに、パラメータを変数ではなく直接数値を書いて渡しています。いわゆる「値渡し」です。

MVCモデルのPHPフレームワーク

このようにMVCモデルのフレームワークを使うと、すっきりと簡単にphpプログラミングができます。htmlとphpをごっちゃにして書いていた頃の悪夢から解放させられて本当に助かりました。

自己紹介のページの一番下に書いてありますが、改めて書きだしておきます。

PHPでWebプログラムを書く場合、そのままではプログラム・コードとhtmlコードが混在して読みにくくなります。もちろん書きにくくてしょうがありません。たいていの場合、ここで挫折します。
そこでテンプレートエンジンを使って画面と制御を分離する手法が使われるようになりましたが、フレームワークはそれをさらに進めた考え方です。これをMVCモデルといいます。
M = Model:データベースへのアクセスなど
V = View:画面表示
C = Controller:全体の制御
という風に別々に書くことで、すっきりとしたコーディングができます。
いろんな種類のフレームワークを試してみて、最後にたどり着いたのが現在使っているものです。

実際にはたくさんのPHPフレームワークがあります。自分に合ったものを見つけて使ってみることをおすすめします。

2013年11月8日 記