PHP応用編

 いよいよ到達しました「PHP応用編」です!このページに初めてやってきた人。「PHPはだいたいわかる」「Xampp使ったことある」という人は以下、読み進んで下さい。「PHPよくわかんねー」とか「Xampp?エ、エックスぅ・・」という人は「はじめに」を見て、どこから見たらいいか確認しましょう。
 話をもとに戻しまして、この応用編では、このサイトで学んできたことを使って、実際によく使われるウェブサービスの機能を作ってみたいと思います。メニューは以下です。
 いずれもシンプルではありますが、ページにアクセスするたびにカウントアップされるアクセスカウンタや、メッセージを交換できる電子掲示板。英単語を入れると訳を出力する電子辞書を作ります。楽しんでやっていきましょう。

SPONSORED LINK


アクセスカウンタを作る

1. 設計と準備

 これまで学んだ知識を使って、ページにアクセスされた回数をカウントするアクセスカウンタを作ります。ユニークアクセスを識別したり、自分(管理者)のアクセスだけカウントに含めないような高機能なものではなく、アクセスするたびにカウントが1ずつ増える簡易のアクセスカウンタです。
 アクセスカウンタの仕組みは、現在までのアクセス数を保存しておいて、アクセスがあるたびにそれを読み出し、1を足して表示すると同時に、足した値を保存しておく、という形になります。
 例えば、ある時点までのアクセス数が「48」だとした場合、次のアクセスがあると、保存されたファイルからその数値「48」を読み取り、1を足した「49」をウェブページに表示すると同時に、「49」を元のファイルに上書き保存しておきます。
 そのため、ファイルは、アクセスカウンタの処理を行うphpスクリプトと、アクセス数を保存しておくデータファイルが必要になります。
 というわけで準備に移りましょう。これまでの準備編や基本編でやってきたので大丈夫と思いますが、応用編の最初なので念のため少し丁寧に。
 まずは「phpファイル」とデータ保存用の「テキストファイル」を作成します。PHP開発環境準備編・作業フォルダHTML復習編・ひな形ファイルの通り、[Xamppフォルダ]-[htdocsフォルダ]に設定した「pkpkiso」フォルダに作った「hina.html」(ひな形ファイル)を[Ctrl]+[c]でコピーして[Ctrl]+[v]を2回やると2つコピーファイルができますので、コピーされたファイルの名前を、一方は「ouyou01.php」、もう一方は「accesscounter.txt」と変更して下さい。
 ファイルができたらまず「ouyou01.php」をテキストエディタ(Terapad等)で開きます。テキストエディタの取り扱いはPHP開発環境準備編・テキストエディタをご覧あれ。ということで、ouyou01.phpを次のように編集します。

  ouyou01.php
  

 説明するまでもありませんがHTMLの基本タグにPHPのプログラムが埋め込まれています。PHPプログラムも「accesscounter.txt」というファイル名を表す文字列を変数「$datafile」に設定し、echo命令でその内容を表示する、というだけです。ブラウザから「http://localhost/phpkiso/ouyou01.php」として実行すると「accesscounter.txt」と表示されて終わりです。できましたか?
 なお応用編からサンプルに所々コメントをつけています。サンプル中「//」(スラッシュスラッシュ)に続けて書かれた説明文みたいなのがコメントです。つまり「//」はphpプログラムのコメント記号。コメントはプログラムに影響しないので書かなくても平気ですが、書いておくと後から「この1行は何の処理だっけ?」と悩まなくても良くなります。特にプログラム初心者は書いておくと理解を助けますし、そうでない場合には特に難しい箇所などピンポイントで使うようにすると便利です。うまく使えるようにしておきましょう。
 話を元に戻して。PHPのファイルができたらもう一つ。アクセスカウンタのカウント数を保存しておくためのデータファイルの設定をしておきましょう。先ほど作った「accesscounter.txt」をTerapadなどテキストエディタで開き、「0」(ゼロ)と半角数字で入力して保存して下さい。全角で入力すると文字として認識されるので足し算ができずエラーになりますので注意です。

  accesscounter.txt
  

 「0」(ゼロ)だけなのでサンプルいらないと思いますが・・・要はこれだけのテキストファイルを作る、ということです。「0」(ゼロ)がどう使われるかはこの後出てきますので今はわからなくて大丈夫。保存まで出来たらテキストエディタは閉じておきましょう。

SPONSORED LINK

 ここまでできたら「ouyou01.php」を動作させてみましょう。そのためにはXamppを起動する必要があります。PHP開発環境準備編・Xamppの起動PHP開発環境準備編・Xamppの設定で確認した通り、Xamppフォルダの「xampp-control.exe」をダブルクリックしてXamppコントロールパネルを開き、Apacheの段の[start]ボタンをクリックしてサーバーをスタートして下さい。
 Xamppが起動したらブラウザで「http://localhost/phpkiso/ouyou01.php」にアクセスして下さい。問題がなければ以下のように表示されるはずです。うまくいかなければよく見直しましょう。これで準備完了です。

  


2. データの読み込みと表示

 まず、現在までのアクセス数を読み込んで表示する処理が必要です。先ほど作った「0」(ゼロ)だけが保存された「accesscounter.txt」は、アクセス数を保存するためのデータファイル、ということになります。というわけで、これを読み込んで表示する処理を作りましょう。
 以下のサンプルを見て「ouyou01.php」を編集して下さい。なお「■■■」の部分は、応用編ということで意図的に伏字にしてあります。「■■■」が3文字とは限りません。考えて入れてみましょう。

  ouyou01.php(php部分以外は省略)
  

 わかりますか?まず最初の2行はOK。3行目はファイルを読み込んでいます。ファイルの読み込みはPHP基本編・ファイル入出力でやりました。ファイルの内容を全て読み込み、1行ずつ配列に格納して処理するんでしたね。何という関数だったでしょうか?答えは・・・file()関数です。合ってましたか?
 続いて4行目。コメントにも書いていますが、ファイルの内容が入った$dt[0]に1を足して、それを$dt[0]に再び代入しています。つまり、アクセスカウンタの値を1増やしているわけです。$dt[0]というのはわかりますね。配列「$dt」の最初の要素です。file()関数は、ファイルを読み込んで行単位でデータを取り出して配列に入れますので、ファイルの1行目が$dt[0]、2行目が$dt[1]、3行目が$dt[2]・・と保存されるはずです。ただ、今回の「accesscounter.txt」には数値データが1つあるだけですので、配列の要素も1つだけ、ということになり、最初の要素の$dt[0]だけ、ということになります。その上で「$dt[0]+1」として、ファイルに格納された数値データに1が加算されて$dt[0]に再設定されている、ということです。
 そのあとは簡単。echo命令で「あなたは~番目のお客さんです」と表示して終了、となります。
 プログラムが書けたら「localhost」経由でアクセスしてみて下さい。「あなたは1番目のお客さんです」が表示されます。表示されたらブラウザの更新ボタンをクリックするか、キーボードの[F5]キーをポンと1回押して再読み込み(=再アクセス)してみて下さい。「1番目のお客さん」から変化はないはずです。何度アクセスしても変わりません。なぜなら前回アクセスをファイルに書き込んで記録していないからです。これではアクセスカウンタとは呼べません。

  

SPONSORED LINK


3. データの保存処理

 そこで、加算したアクセス数を表示させるだけでなく、保存しておく処理を追加します。ファイルへのデータの書き込みもすでにやりましたね。私たちが普段、ワードやパワポやテキストのファイルを使う場合と同様に、開いて、編集、保存して、閉じる、という流れです。実際には、以下のサンプルにあるような形で処理します。
 また「■■■」があります。「■■■」は3文字とは限りませんよ。1文字かもしれませんし、もっと多いかもしれません。

  ouyou01.php(php部分以外は省略)
  

 解説します。まず5行目までは変更なし。ファイルから現在までのカウントデータを読み込んで1を足して表示する、という処理です。追加したのはその次からの3行。
 まず「$fp=fopen($datafile,'■■■');」。fopen()関数を使ってファイルを読み込み、管理情報を変数に代入する、という処理です。では「■■■」の部分は何が入るでしょうか?コメントを見ると「上書きモードで開く」とあります。「accesscounter.txt」は、現在までのアクセス数を保存するためのファイルですので、1増やした値を上書きして更新するわけです。そして上書きモードの指定を「■■■」の部分で行うんでしたね。上書きモードですので、ここには「w」(ダブリュー)が入ります。「write」の「w」です。
 次の行の「■■■($fp, $dt[0]);」は何でしょうか?ファイルを開きましたので、コメントにもあるようにここでは新たなアクセス数を保存する必要があります。ですのでここではファイルを書き込む関数を指定すればOK。ここで「■■■」に入るのは・・・「fwrite」関数です。合ってましたか?
 そして開いたファイルへの処理が終わったら閉じるんでしたね。次の行は「fclose($fp);」となっておりfclose()関数で開いたファイルを閉じています。このあたりのファイルの取り扱いがよくわからない場合はPHP基本編・ファイル入出力を確認して下さい。
 完成したらブラウザで確認して下さい。「あなたは1番目のお客さんです」と表示されたらまずは成功。その後、ブラウザで再読込(更新)してみましょう。再読込する度に「あなたは2番目のお客さんです」、「あなたは3番目のお客さんです」・・・とカウントが増えていきますか?増えていけば、カウンタとして正常に機能していることになります。

  


4. 現在時刻の表示

 アクセスカウンタの基本機能としてはこれでOKですが、せっかくなのでもう少し機能を追加してみましょう。
 まずは、今アクセスした日時を表示させてみたいと思います。「あなたは~番目のお客さんです」と表示した後に「只今の到着時刻は/12/10 14:15:37です」と表示するようなものを目指しましょう。
 ではどうするか?PHPで日時を取得するためには「date()」関数を使います。この関数は、現在日時や指定された日時を任意の形式でフォーマットして日付文字列を返す処理を実現するものです。

SPONSORED LINK

 例えば、現在時刻を「/09/08 07:00:03」と表示したい場合、次のように指定します。

  echo date ('Y/m/d H:i:s');

 あるいは直接表示しなくても日時の文字列を変数に入れることも可能です。今度は日本語表記にして「年01月07日 09時05分08秒」という形式の日時の文字列を変数に設定する場合、次のように指定します。$hogeという変数に日時の文字列を代入する形です。

  $hoge = date ('Y年m月d日 H時i分s秒');

 わかりますか?日時文字列の出力形式を「Y」や「m」や「s」などの記号と文字を使って指定しているわけです。実際には「年月だけでいい」とか「秒表示いらない」とかいろいろあると思いますが、その場合は、年月部分だけにしたり、秒のところを設定しなければ、必要な部分だけ表示されます。この表示形式は様々なものが用意されています。よく使いそうなものだけ紹介します。

記号説明
Y年。4桁表記1999や
y年。2桁ゼロ詰め99や07や
m月。2桁ゼロ詰め01から12
n月。1~2桁。ゼロ詰めなし1から12
M月。英3文字短縮形式JanからDec
d日。2桁ゼロ詰め01から31
j日。1~2桁。ゼロ詰めなし1から31
w曜日。数値0(日曜)から6(土曜)
D曜日。英3文字短縮形式SunからSat
H時。24時間表記。2桁ゼロ詰め00から23
h時。12時間表記。2桁ゼロ詰め01から12
a午前または午後(小文字)amまたはpm
i分。2桁ゼロ詰め00から59
s秒。2桁ゼロ詰め00から59

 それではプログラムを考えましょう。必要なのは、現在時刻を取得する処理と、それを表示する処理です。どうしたらよいでしょうか?以下のサンプルを試しましょう。「■■■」は考えてみて下さい。これまでと同様「■■■」が3文字とは限りませんよ。

  ouyou01.php(php部分以外は省略)
  

 追加したのは2行だけです。一つは5行目。「$jikan = ■■■('Y/m/d H:i:s');」としています。変数名が$jikanですし、時間の表示フォーマットを設定していますし、今やったばかりですのでわかりますよね。「■■■」には「date」が入ります。date()関数で現在時刻を取得して表示形式を指定して変数に代入しています。
 もう一つは、その2つ下の7行目。これは簡単ですね。echo命令で「只今の到着時刻は~です」と表示しているだけです。
 編集できたら動かしてみましょう。「localhost」経由で表示してみて下さい。うまく表示されましたか?日付や時間がズレているかもしれません。Xamppの設定の影響です。この次で説明しますので、とりあえずここではそれでOKです。ポイントは、更新するたびにアクセス回数が増えるのと同時に到着時刻も変化していくかどうかです。うまくいかない場合はよく見直しましょう。

  

SPONSORED LINK


5. 時差への対応

 PHPで日時を操作する関数を取り扱うようになると出てくるのが時差の問題です。実はこの資料を作っているのは日本時間の21時。夜9時です。でも上の出力イメージの時間を見て下さい。「13:00:41」となっています。つまりお昼の13時と表示されているわけです。
 この原因は、PHPの時間とユーザーの時間がずれているために起こります。PHPの時間は、そのPHPエンジンを動かす際に従う基本的な時間ということになります。世界標準時設定なのか、東京時間なのか、ニューヨーク時間なのか・・・といった設定です。その設定と、開発者でありユーザーである我々の時計とがズレていると時差問題が起きます。
 こうした問題への対処方法としては2つ。一つ目はXamppの設定を変えることです。詳しくは各自調べていただければと思いますが、Xamppには、php.iniという設定ファイルがあり、その中のタイムゾーンに関する設定値を「date.timezone = Asia/Tokyo」と変更すると、そのXamppは東京時間になります。
 ただこの対処の仕方には問題があって、開発環境では東京時間になっても、そのPHPプログラムを公開するレンタルサーバーなどの設定が東京時間になっているとは限らないということ。ネット経由でアクセスするサーバーが世界のどこに置いてあるかなんて知りませんし。
 それから、サーバーの時刻設定は変えられるとは限りませんし、プログラムによっては海外ユーザーを想定したサービスを提供しますので、変えてしまって他のプログラムに影響が出る可能性もあります。
 というわけで、PHPの設定を変えることなく、プログラム的にタイムゾーンを設定するためには次の関数を使います。

  date_default_timezone_set ( 'Asia/Tokyo' );

 PHPプログラムの中で、date()関数など日時を扱う関数を使う前にこれを実行しておけば、東京時間に合わせられます。もちろん「Asia/Tokyo」以外にも世界中のタイムゾーンに対応した設定値があります。ここでは書ききれないので、必要が生じたら調べてみて下さい。一応、サンプルは次のようになります。「■■■」は簡単ですね。編集したら動作を確かめてみましょう。以下の出力イメージもこの資料を作成している現在時刻通り「21:02:14」となりました。めでたしめでたし。

  ouyou01.php(php部分以外は省略)
  

  


6. アクセス履歴の保存

 日時データを取得することができるようになったので、アクセスカウンタにもう一つ機能を追加しましょう。それは「(前回のアクセス時刻は2013/12/19 11:35:48です)」と前回のアクセス履歴を表示する機能です。
 どう実現したら良いでしょうか?date()関数は、phpスクリプトが処理された時点の日時を返す関数ですので、過去にアクセスした日時はわかりません。
 「アクセス日時をファイルに記録しておいて、次にアクセスしたときに、その日時データを読み込んで表示すればいいのでは?」と思いついた人はセンスがあります。これまで学んだ知識で実現するには、それが正解です。
 では実現方法はどうすれば良いでしょうか?これまでのアクセス数を保存するファイルの他に日時データを保存するファイルを作るという方法があります。ただ、日時データを保存するだけのために、もうひとつファイルを作るというのも管理上面倒ですし、ファイルが2つあるということは「ファイルを開いて保存して閉じる」というファイルアクセスを最低2回はやらないといけません。

SPONSORED LINK

 そこでアクセス数を記録する「accesscounter.txt」に、日時データも一緒に書き込み、一度に読み出して表示する、ということを考えます。そこでまずは、日時データを保存するところから考えます。
 日時データを「accesscounter.txt」に保存する方法も、いくつかあります。現在、アクセス数の数値だけが保存されていますので、その横に、カンマなどの区切り文字を入れて・・

3,/12/19 11:55:17
 

 ・・と入力させる方法もあります。この例では、3回アクセスがあり、3回目のアクセスが、年12月19日の11時55分17秒にあった、という意味です。
 ただ、この方法ですと、ファイルのデータを読み出した後、区切り文字のカンマを基準にデータ を切り分ける処理を考えなくてはなりません。explode()関数を使えばできますが、データの「読み出し」とデータを「分割して配列に格納」を2段階でやらなくてはなりません。
 一方で、file()関数を使ってファイルのデータを読み込めばどうでしょうか?file()関数はテキストファイルのデータを1行1行読み取って配列に格納してくれる関数でした。つまり、file()関数を使えば一発でデータを「読み込んで配列に格納」ができることになります。
 というわけで、file()関数で読み出すことを想定して保存方法を考えておくと後々便利です。つまりアクセス数の数値データと前回アクセスの日時データをを「カンマ区切り」ではなく「改行区切り」でファイルに書き込んでおくわけです。日時データが次の行に保存されたイメージは次のようになります。

3
/12/19 11:55:17
 

 つまりは、file()関数を使えば、区切り文字を使わなくても、以下のようにテキストファイルのデータを取り出せるわけです。

  配列[0] ← 1行目の「3」が格納される
  配列[1] ← 2行目の「/12/19 11:55:17」が格納される

 というわけで、テキストファイルにこのような改行区切りでデータを保存しましょう。どうしたら良いでしょうか?
 方法としては例えば、アクセス数を保存しているファイルをfopen()関数の「aモード」つまり追記モードで開き直して追加するという方法があります。しかし、何度もファイルを開いたり閉じたりするのは負荷が大きいので避けたいところ。
 そこでもうひとつの方法は、ファイルに書き込む文字列に「改行」も含めて、ひとかたまりの文字列データとして一緒に保存してやる、というやり方です。「データ1」と「データ2」を別々に書き込むのではなく、「データ1(改行)データ2」という一連の文字列データとして一度に書き込む、という方法です。ここではこのやり方でいきましょう。
 改行の設定の仕方はわかりますか?「"¥n"」という特殊文字を使うんでしたね。HTMLの改行は「<br>」でしたが、PHPでの改行は「"¥n"」でした。ですので「アクセス回数」と改行記号「"¥n"」と「アクセス日時」を連結してテキストファイルに保存すればOK、ということになります。
 ではこれをサンプルを参考に実現してみましょう。いずれもこれまでやったことなので大丈夫なはずです。「■■■」には何が入りますか?3文字ではありませんよ。

  ouyou01.php(php部分以外は省略)
  

 変更すべきは1か所だけ。「■■■」の箇所だけです。コメントもヒントになってます。fwrite()関数でデータを書き込む内容として・・・「$dt[0]."¥n".$jikan」というのが正解の一つです。アクセス回数が格納された$dt[0]と改行記号"¥n"と現在日時が格納された$jikanを連結してとめてファイルに書き込め、と指示しているわけです。わかりますよね。
 完成したら、ブラウザでaccesscounter.phpにアクセスして下さい。もちろん「localhost」経由です。エラーなどが出なければ、とりあえずOKとして、その後「accesscounter.txt」をテキストエディタで開いて確認しましょう。以下のイメージの通り、1行目にアクセス回数、2行目にアクセス日時のデータが保存されていたらうまくいったということです。

  


7. アクセス履歴の表示

 アクセス日時のデータが保存できるようになったら、そのデータを読み込んで表示する処理を作ります。といっても、file()関数で「accesscounter.txt」からデータを読み込んで「$dt」という配列に格納するという処理は、上ですでに作りましたので簡単です。

SPONSORED LINK

 今回「accesscounter.txt」には2行のデータが保存されていますので、配列には以下のようにデータが取り込まれます。今更ですが配列の添字は0からはじまります。

  $dt[0] ← 「accesscounter.txt」の1行目=前回までのアクセス回数
  $dt[1] ← 「accesscounter.txt」の2行目=前回アクセス日時

 というわけで、このことを使えば、前回アクセスした日時を表示することができます。これも大丈夫ですよね。下の「■■■」は考えて下さい。

  ouyou01.php(php部分以外は省略)
  

 編集できたら、ブラウザでouyou01.phpを読み込んでみて下さい。ブラウザに、以下のように表示され、更新するたびにアクセス回数が増え、現在時刻と前回時刻が変化したら完成です。

  


8. 部品として使う

 ここまで、アクセスカウンタの基本機能を作りました。ただ、これはphpファイルとして動作させるタイプです。つまり、~.phpというファイルの中でなら、phpスクリプトとして動作するが、~.htmlというファイルでは、そのまま使うことはできません。
 サーバー側の設定で、~.htmlの中でもphpスクリプトを処理できるようにすることは可能ですが、サーバーによっては設定できたりできなかったりします。ですので、できればアクセスカウンタのphpスクリプトを、外部の部品として、htmlファイルの中で呼び出して使うことができると便利です。実際、多くのアクセスカウンタの無料サービスも、何らかのプログラムをhtmlファイルの中で呼び出して使えるようになっています。
 そこで、皆さんが作ったphpスクリプトを、php部品として使えるようにする方法にチャレンジします。今回は、htmlファイルの中で、外部のjavascriptファイル(~.js)を呼び出す要領でphp部品(~.php)を呼び出し、呼び出されるphp部品は、javascriptのテキスト表示関数を出力することで呼び出しに応える、というやり方です。少し裏技っぽい方法ですが、一般的なサービスでもよく使われているようです。
 なおjavascriptはブラウザで動作するプログラム言語です。突然javascriptなんて出てきたので驚いたかもしれませんがご心配なく。ここでは詳しくやりませんので「へーそんなのがあるんだ」ぐらいで見ていただけれOK。興味を持った人は調べてみて下さい。
 まず、準備として、先ほど作った、ouyou01.phpをコピーし、ouyou01b.phpに名前を変更、テキストエディタで開いて下さい。開いたら、まずphpスクリプト以外のhtmlのタグをすべて削除し、純粋なphpだけのファイルにします。phpスクリプトは「<?php ~ ?>」部分ですので、それ以外の部分を削除します。

  ouyou01b.php
  

 次に、このphpファイルから「出力された結果」が、javascriptであることを宣言するために、header()関数を使います。「単なる出力」を、「javascriptによる出力」にしてやるわけですね。
 そこで、phpスクリプトのアクセスカウンタのメッセージ表示の前後に、以下のように追記して下さい。3行分追加しています。7行目、8行目と12行目が追加した箇所です。コメントで★マークをつけてます。

  ouyou01b.php
  

SPONSORED LINK


 編集が済んだらブラウザで「localhost」経由でouyou01b.phpにアクセスしてみて下さい。ブラウザによっては、以下のように表示されます。javascriptのコードが出力されていることが確認できます。ですがブラウザのセキュリティ上ダウンロードを求められる場合があり、この資料を作成するために使ってきたIE11ではダメでした。Chrome70とFirefox63はOKでした。以下のイメージはFirefoxの出力です。うまくいかない場合は別のブラウザで確かめるか、ブラウザがなければパスして次に進んでいただいて構いません。

  

 ここで確かめたかったことは「ouyou01b.php」が、javascriptの命令である「document.write(~);」を出力している、という事実です。なお正確には、document.write(~)は、documentオブジェクトのwriteメソッド、と言います。
 それでは、アクセスカウンタのphp部品を呼び出す側の、テスト用htmlファイルを作成します。hina.htmlをコピペして、名前を「ouyou01.html」に変更し、テキストエディタで開いて下さい。そのうえで以下のように編集して下さい。

  ouyou01.html
  

 このプログラムのキモは、<script>タグの行。下から4行目です。通常、javascriptの外部ファイル「~.js」を呼び出す時に使う書き方ですが、これによってphp部品「ouyou01b.php」を呼び出しています。php部品を作る際に「document.write(~)」というjavascriptの命令を出力していたのはこのためです。ここのjavascriptも「ふーんそんなのもあるんだー」で構いません。
 完成したらブラウザで「localhost」からouyou01.htmlにアクセスしてみましょう。以下のように表示され、再読込するたびにデータが更新されればOKです。つまり、このアクセスカウンタは、様々なHTMLからjavascriptを使って呼び出して使えるPHP部品として使える、ということです。もっと言えば、アクセスカウンタの処理を別処理に変えれば、アクセスカウンタ以外のPHP部品も使えることになります。便利なのでぜひ覚えておいて下さい。

  


ページのトップへ戻る
SPONSORED LINK