PHP動的Webサイト作成入門

Copyright(C) 25Feb2014 coskx TNCT

0.はじめに

この文書はPHPによる動的Webページの作成方法を解説する。
次のことが前提となっている。
(1)学習者が簡単なhtml文書を書くことができること
(2)PCにapacheおよびPHPがインストールされているPCに対して作業できるか,または
   インストールされているPCで,作業できる環境にある。

Webサーバ側で動作するプログラムの文字列出力によって,htmlファイルのような出力を生成し,
ブラウザ側に送り,ブラウザが表示しているという流れがつかめたら学習成功と考えてよい。
細かなPHPの文法や作法は,Web検索で見つけられる。

このページからリンクされている関連ページ
フォーム部品使用プログラムサンプル
ちょっと大きなアンケート
アンケート自動生成
PHPプログラムパーツ

想定する学習環境
WindowsPC使用 windows 7 8
WebサーバApacheが導入されており,「c:\Apache2.2」にインストールされている。
標準設定で,ドキュメントルートが
「c:\Apache2.2\htdocsに設定されている。」
phpが
「c:\php」にインストールされている。

インストール例
Apache,PHP,MySqlインストールと設定メモ
SSLの導入についてもこのメモ中に説明がある。
 メモページapache2.2.25とphp5.3.28,mySql5.6.16
 メモページapache2.4.10,php5.6.4,mySql5.6.16
 メモページapache2.2.25を2.2.29にアップデート




情報工学科1F電算室では上記学習環境が設定されており,本ページの内容が演習できるようになっている。
起動の仕方

作成したhtml文書の閲覧の仕方



1.通常のWebページ

TeraPadなどのエディタを使って,デスクトップ上にTable 1.1の左側のようなファイルhello.html
を作る。そのアイコンをダブルクリックするとブラウザが立ち上がって,
「file:///C:/Users/xxxx/Desktop/hello.html」を見ることになり,
Table 1.1の右側のように見える
(これはテスト用なので,最小限のことだけを記述している。)
これは自分のPC内のHTMLファイルを見ていることになる。



c:\Apache2.2\htdocs にhello.htmlをコピーして,Webブラウザから
 http://localhost/hello.html
で見ることができる。ApacheはWWWサービスを行うサーバアプリケーションである。
WebサーバとクライアントPCが同じ1つのPCであるが,これはWebサーバとブラウザが異なるPC上で動作している場合と同等である。



他のマシンからこれを見るには,
 http://サーバマシンのIPアドレス/hello.html
または,DNSサーバに登録されていれば
http://サーバマシンのドメイン名/hello.html
として見ることもできる。
(情報工学科演習室PCではファイアウォールが遮断しているため,他のマシンからの閲覧は出来ない)

Webブラウザの要求にしたがってWebサーバはhtmlファイルの内容をブラウザに送り,
Webブラウザは送られてきた内容(これはhtmlファイルそのもの)を解釈して表示する

Table 1.1 htmlファイルの表示
htmlファイル
(hello.html)
ブラウザでの表示
 (http://localhost/hello.html)
<html>
<body>
Hello world!<br>
</body>
</html>
Hello world!

デスクトップにあるファイル名hello.htmlをhello.phpに変更した場合,直接ブラウザで見ると,
file:///C:/Users/xxxx/Desktop/hello.phpのようにすると直接見える
ファイルの中身がそのまま(エディタで見ているのと同じ)として見えてしまう。

apacheが起動しているのであれば,先ほどの
c:\Apache2.2\htdocsの公開用フォルダに
hello.phpを入れて,Webブラウザから

http://localhost/hello.php
とすれば,元通りに見えるようになる。
(localhostというのは自分のPCのことを表します。)


他のマシンからこれを見るには,
http://サーバマシンのIPアドレス/hello.html
または,DNSサーバに登録されていれば
http://サーバマシンのドメイン名/hello.html
として普通に見られる。
(情報工学科演習室PCではファイアウォールが遮断しているため,他のマシンからの閲覧は出来ない)

Table 1.2 phpファイルの表示
phpファイル
(hello0.php)
apache経由で,ブラウザでの表示
(http://
localhost/hello0.php)
ブラウザの機能でソースファイル
を表示してみると
<html>
<body>
Hello world!<br>
</body>
</html>
Hello world!
<html>
<body>
Hello world!<br>
</body>
</html>



2.PHPプログラムの第一歩


2.1 PHPでのプログラム


PHPはhttp://www.php.net/で配布されているオブジェクト指向の記述言語である。
PHPがPCインストールしてあれば,そのPC上でプログラムを動かすことができる。
まず,windowsPCで簡単なプログラムをコンソール(Windowsのコマンドプロンプト)上で動かしてみよう。
挨拶を
表示して,九九の表を表示するプログラムである。

phpプログラムは「<?php」と「?>」の間に記述する。
変数は$で始まる名前が使われ,宣言なしで使える。forループなどはC言語と同様に使える。
printfも使える。

以下の例は,php.exeを起動して,(
phpのインストールされたディレクトリはC:\php
ディレクトリDesktopにあるconsolehello.phpを起動したものである。
(カレントディレクトリもDesktopである)
一般的には第一引数にphpプログラムソースファイル名を与えて,php.exeを起動すれば良い。
ただし,カレントディレクトリおよびphp.exeがインストールされているディレクトリに注意すること。
もし,それらに惑わされたくなかったら,このコマンド使うと良い。→  go_php_on_console.cmd
.phpファイルをこの.cmdにドロップするだけで起動する。
Table 2.1 簡単なphpプログラム
phpソースファイル (consolehello.php)
コンソールでの表示
<?php
/*コメントはこのように書きます*/
//コメントはこれでもOKです。
//変数名は$で始まる

print "Hello world!\n";
for ($xx=1; $xx<10; $xx++) {
    for ($yy=1; $yy<10; $yy++) {
        printf("%4d",$xx*$yy);
    }
    print "\n";
}
?>

C:\Users\xxxx\Desktop>c:\php\php consolehello.php
Hello world!
   1   2   3   4   5   6   7   8   9
   2   4   6   8  10  12  14  16  18
   3   6   9  12  15  18  21  24  27
   4   8  12  16  20  24  28  32  36
   5  10  15  20  25  30  35  40  45
   6  12  18  24  30  36  42  48  54
   7  14  21  28  35  42  49  56  63
   8  16  24  32  40  48  56  64  72
   9  18  27  36  45  54  63  72  81

C:\Users\xxxx\Desktop>


次のようなprint文で書かれたプログラムであれば,当たり前だがtable 1.1のhtmlファイルの内容を表示する。
Table 2.2 簡単なphpプログラム
phpソースファイル (hello.php)
コンソールでの表示
<?php
print "<html>\n";
print "<body>\n";
print "Hello world!<br>\n";
print "</body>\n";
print "</html>\n";
?>

C:\Users\xxxx\Desktop>c:\php\php hello.php
<html>
<body>
Hello world!<br>
</body>
</html>

C:\Users\xxxx\Desktop>


2.2 PHPでhtmlを表示する


table 2.2 のファイルを,Webサーバの公開用ディレクトリに置いて,ブラウザで見てみよう。
例えば,Webサーバapacheの公開用ディレクトリhtdocsにtable 2.3(table 2.2と同じもの)のプログラムを置いて,同じPC上でWebブラウザからhttp://localhost/hello.phpで見る。



Webサーバはphpが出力した内容(table 2.2のコンソール出力)をブラウザに送り,
Webブラウザは送付されてきた内容を解釈して表示する。
ブラウザから見ると,htmlファイルがそのまま送られたのか,phpが生成した内容が送られたのか区別はつかない。
ブラウザ側でソース表示をして見比べるとよい。
Table 2.3 phpプログラムでhtmlの生成と表示
PHPファイル (hello.php)
ブラウザでの表示
 (http://localhost/hello.php)
ブラウザの機能でソースファイル
を表示してみると
<?php
print "<html>\n";

print "<body>\n";

print "Hello world!<br>\n";

print "</body>\n";

print "</html>\n";
?>
Hello world!
<html>
<body>
Hello world!<br>
</body>
</html>

phpのプログラムは次のように,必要なところだけにすることができる。
Table 2.4 phpプログラムでhtmlの生成と表示
PHPファイル (hello2.php)
ブラウザでの表示
 (http://localhost/hello2.php)
ブラウザの機能でソースファイル
を表示してみると
<html>
<body>
<?php
    print "Hello world!<br>\n";
?>
</body>
</html>
Hello world!
<html>
<body>
Hello world!<br>
</body>
</html>

このように,PHPのプログラムはApacheと連携して,サーバ側で動作して,プログラムが生成する標準出力をブラウザ側に送るようにできている。

●ポイント
PHPプログラムがprint文などで出力した結果をWebサーバは受け取り,htmlファイルのように見せかけてブラウザに送っている。

PHPはサーバーサイドスクリプト言語である。逆にjavascriptはWebブラウザ側で動作するプログラムなので,クライアントサイドスクリプト言語である。

お試し

先ほどのTable 2.1のconsolehello.phpをWebサーバの公開用ディレクトリhtdocsにおいて,ブラウザで見ると,改行表示は乱れているが,それらしく 表示される。表示が乱れるのは,htmlにおいて複数の連続した半角スペースは1つの半角スペースになってしまい,また「\n」の改行は無視されるからで ある。(改行したいときは<br>と書かなければならない。)ただし,ブラウザの機能の「ソースの表示」でみると,コンソールに見たものと同じものが見える。

Table 2.5 consolehello.phpをサーバをとおして見る
ブラウザでの表示
 (http://localhost/consolehello.php)
ブラウザの機能でソースファイル
を表示してみると

 (consolehello.php)
Hello world! 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81 > Hello world!
   1   2   3   4   5   6   7   8   9
   2   4   6   8  10  12  14  16  18
   3   6   9  12  15  18  21  24  27
   4   8  12  16  20  24  28  32  36
   5  10  15  20  25  30  35  40  45
   6  12  18  24  30  36  42  48  54
   7  14  21  28  35  42  49  56  63
   8  16  24  32  40  48  56  64  72
   9  18  27  36  45  54  63  72  81

htmlにおける改行は「\n」ではなく「<br>」なので,
consolehello.phpで「\n」を「<br>\n」に置き換えると
ブラウザ上で正しく表示される。


3.PHPプログラムによる動的ページ

PHPプログラムで動的ページを作ってみる。
ここでの動的というのは,プログラム作成時には確定しておらず,Webブラウザから呼び出された時点で内容が確定するという意味である。
例として,Webブラウザから呼び出された時の日付を表示するプログラムである。「.」は文字列連結の演算子である。
日付取得関数dataに関しては使い方を「php date」で検索するとよい。
Table 3.1 phpプログラムで日付表示
PHPファイル (showdate.php)
ブラウザでの表示
 (http://localhost/showdate.php)
<html>
<body>
<?php
    print "今日は," . date('F d Y l') . "です。<br>";
?>
</body>
</html>
今日は,February 26 2014 Wednesdayです。


4.Webブラウザとのテキストデータのやり取りを行う動的ページ(挨拶ページ)

フォーム(htmlの部品)を用いてWebブラウザとWebサーバ相互でデータのやり取りを行う。
最初のWebページでユーザがWebブラウザで自分の名前を入力して送信ボタンを押すと,Webサーバにデータが送られ,
別のWebページにて,「○○さんこんにちは」と表示する。
Table 4.1 phpプログラムで○○さんこんにちは
PHPファイル (yourname1.php)
ブラウザでの表示
(http://localhost/yourname1.php)
<html>
<body>

<?php
print "あなたのお名前は?<br>\n";
?>
<form action="yourname2.php" method="post">
    <input type="text" size="30" name="username"><br>
    <input type="submit" name="soshin" value="送信">
</form>

</body>
</html>
あなたのお名前は?





あなたのお名前は?




PHPファイル (yourname2.php) 送信ボタンを押すと
自動的にyourname2.phpに進んで
<?php
    if(isset($_POST['username']) == true) {
        $yourname = $_POST['username'];
    } else {
        $yourname = "あれれ,わかんない";
    }
?>
<html>
<body>

<?php
print $yourname . " さん,こんにちは<br>";
?>

</body>
</html>
東京 太郎 さん,こんにちは

yourname1.php補足説明
このプログラムは,phpで書かなければならない理由はなく,html文書で書くことができる。
<form action="yourname2.php" method="post">
  「action=」のところにはsubmit型ボタンが押されたときに進む先のURLを書く。
  ここでは同じディレクトリ内の移動なので行き先のファイル名が書いてある。
  「action=」を省略すると自分自身向けとなる。
<input type="text" size="30" name="username">
  「type="text"」フォーム内の部品の種類がテキスト入力ボックスであることを表す。
  「name=」は,次のWebページに持っていく値(ここでは「東京 太郎」)の入っている
  箱の名前(ここではusername)を書く。
  「size="30"」はテキスト入力ボックスの横幅
<input type="submit" name="soshin" value="送信">
  「type="submit"」フォーム内の部品の種類が「アクション起動ボタン」であることを表す。
  使われていないが箱の名前は
soshinで箱の中身の値は文字列「送信」である。
  値の文字列「送信」はsubmit型ボタン上に表示される。
<form ・・・ </form>の内容はphpとは関係なく,htmlの記述の1つである。
yourname2.php補足説明
$_POST['username']
  usernameという箱の中身を表す。ここでは「東京 太郎」が入っている。
  
キーポイントusernameという名前をyourname1.phpと共通にすることによって,
  値の送り・受けができている。

isset($_POST['username']) == true
  usernameという箱が存在したら(が作られていたら)の意味。
  isset(変数)はその変数が存在するかどうかを検査する関数である。
  もし,yourname1.phpを経由せず,直接yourname2.phpが呼び出されたら,
  $_POST['username']は送られてこないので
  isset($_POST['username'])はfalseとなり,「あれれ,わかんない・・・」が
  表示される。
$で始まる文字列は変数名である。C言語のような変数宣言はない。
  $_POSTもシステムの変数で,連想配列である。

yourname1.phpで送信ボタンを押すと,yourname2.phpには次の二つの値が送られてきている。
(1)
$_POST['username']には入力された「東京 太郎」が値として入っている。
(2)
$_POST['soshin']にはvalue=で設定された「送信」が値として入っている。
yourname2.phpでは$_POST['username']が受け取れていたらある動作をすればよいので,
$_POST['soshin']については受け取ってはいるが,使っていない。

yourname2.phpが表示されている状態で,ブラウザの機能でソースファイルを表示してみると
次のようになっていることがわかる。
<html>
<body>
東京 太郎 さん,こんにちは<br>
</body>
</html>

★★見落としてはならないこと
ここで行なったことはフォーム送信であり,<form>と</form>で囲まれ た中に送りたい内容を書く。type="submit"になっているボタンを押すことで,<form>と</form>で囲まれ た中のデータを送信する。
送信されるデータは箱に入っており,その箱にはname=""で指定された名前が付いている。


★★セキュリティ上の問題
上記のphpプログラムでの文字列入力と表示は文法的には正しいが2つの問題点がある
(1)htmlで使われる「<」や「>」などが表示できない。
   ここでは人の名前入力だからそのような入力はないが,一般的な文字入力ではありうる。
(2)悪意を持ったユーザが名前ではなく,異常な動作をするプログラムを入力できてしまう。
   これは非常に危険な状態である。
対処方法:ユーザが入力した部分では特殊文字を変換して表示する関数htmlspecialcharsを使う。

変更前
<?php
    if(isset($_POST['username']) == true)
    {
        $yourname = $_POST['username'];
    } else {
        $yourname = "あれれ,わかんない";
    }
?>

変更後
<?php
    if(isset($_POST['username']) == true)
    {
        $yourname = htmlspecialchars($_POST['username'], ENT_QUOTES);
    } else {
        $yourname = "あれれ,わかんない";
    }
?>


実験
変更前のyourname1.phpにおいて,ブラウザの「あなたのお名前は?」の次の行のテキスト入力ボックスに次の内容を書き込んで送信ボタンを押してみよう。
<a href='https://www.google.co.jp'>Tokyo</a><script>alert('Hello');</script>
多くのブラウザではyourname2.phpの画面で「Tokyo」がリンクになっていて,クリックするとgoogleにジャンプするようになる。また,Helloを表示するアラートボックスが表示されるブラウザもある。
これは,セキュリティ上もっと危ないこともできることを意味している。
変更後のphpであればこのようなことは起きない。





5.テキストデータの処理を行う動的ページを1つのphpファイルで実現

「4」では2つのphpファイルを使用したが,1つのファイルにまとめてみる。formのaction=の設定で
自分自身を指すようにしておけば,送信ボタンにより自分自身に移動できる。
(「action=」を省略すると自分自身向けとなる。)
実はformのaction=の設定を省略すると,自分自身への移動を設定したことになる。
また,1度目の呼び出しか,「送信」ボタンによる2度目の呼びだしかは,isset($_POST['username'])
で判断できる。すなわち,$_POST['username']を受け取っているということは,「送信」ボタンによる2度目
の呼びだしだと判断できる。
Table 5.1  phpプログラムで○○さんこんにちは(2)
PHPファイル (yourname.php)
ブラウザでの表示 (http://localhost/yourname.php)
<?php
    if(isset($_POST['username']) == true) { //「usernameという箱に入った変数
                                            //
を受け取れたら」というわけだか
                                            //ら,1回目の呼び出しでは,ここ
                                            //には入らない。
        $yourname = htmlspecialchars($_POST['username'], ENT_QUOTES);
        $firsttime = false;
    } else {                                //一回目の呼び出しではこちらに入る
        $firsttime = true;
    }
?>
<html>
<body>

<?php
    if ($firsttime == true) {
        print "あなたのお名前は?<br>\n";
        print "<form method=\"post\">\n";
        print "<input type=\"text\" size=\"30\" name=\"username\"><br>\n";
        print "<input type=\"submit\" name=\"
soshin\" value=\"送信\">\n";
        print "</form>\n";
    } else {
        print $yourname . " さん,こんにちは<br><br>";
        print "もう一度試しますか?<br>\n";
        print "<form method=\"post\">\n";
        print "<input type=\"submit\" name=\"
soshin\" value=\"もう一度\">\n";
        print "</form>\n";
    }
?>

</body>
</html>

あなたのお名前は?




-----------------------------

あなたのお名前は?




-----------------------------
東京 太郎 さん,こんにちは

もう一度試しますか?



-----------------------------


あなたのお名前は?




phpプログラムでは,途中でプログラムの記述をやめて,必要なところでプログラム記述を再開できるので,Table 5.2のような表現も可能である。
しかし,Table 5.2の方が部品の可読性はよくなるが,流れの可読性が劣るように思われる。

Table 5.2  phpプログラムで○○さんこんにちは(3)
<?php
    if(isset($_POST['username']) == true) {
        $yourname = htmlspecialchars($_POST['username'], ENT_QUOTES);
        $firsttime = false;
    } else {
        $firsttime = true;
    }
?>

<html>
<body>

<?php if ($firsttime == true) { ?>
        あなたのお名前は?<br>
        <form method="post">
            <input type="text" size="30" name="username">
            <input type="submit" name="
soshin" value="送信">
        </form>
<?php } else { ?>
        <?php print $yourname . " さん,こんにちは<br><br>";
?>
        もう一度試しますか?<br>
        <form method="post">
            <input type="submit" name="
motto" value="もう一度">
        </form>
<?php } ?>

</body>
</html>

フォームの部品には,ラジオボタン,チェックボックス,ポップアップリスト,複数行にわたるテキスト入力ボックスなどがある。これらは<input type="radio" ・・・>,<input type="checkbox" ・・・>,
<select ・・・option・・・>,<input type="textarea" ・・・>のように記述される。
受け取り側は,nameで値の入った箱の名前を指定し,$_POST[箱の名前]で取り出すようになる。
これらのフォーム部品のプログラム例 formparts.html
詳細はWeb検索で調べるとよい。



★★参考 postとget

ブラウザからWebサーバデータを渡しながらhtmlページをリクエストする時には2つのリクエスト方法があり,1つはpostでもう一つはgetである。
getを使うと,urlの記述内に,データを埋め込むことになるが,その作業はブラウザが自動的にやってくれる。
(url記述欄で,何を送信しているか見ることができる。)
postを使う場合はデータはリクエストボディに記述されることになるのでブラウザ利用者が送信内容を見るとはない。

次の例は table 5.1 のusername.php(post送信)をget送信に書き換えたものである。
$_POST['username'] が $_GET['username'] に書き換わり,
<form method=\"post\"> が <form method=\"get\"> に書き換わっているだけである。

本質的ではないが,説明のため,ボタンのvalueを英語にした。

table 5.3 phpプログラムで○○さんこんにちは(4)
PHPファイル (yourname_GetVer.php)
<?php
    if(isset($_GET['username']) == true) { //「usernameという箱に入った変数
                                           //を受け取れたら」というわけだか
                                           //ら,1回目の呼び出しでは,ここ
                                           //には入らない。
        $yourname = htmlspecialchars($_GET['username'], ENT_QUOTES);
        $firsttime = false;
    } else {                                //一回目の呼び出しではこちらに入る
        $firsttime = true;
    }
?>
<html>
<body>

<?php
    if ($firsttime == true) {
        print "あなたのお名前は?<br>\n";
        print "<form method=\"get\">\n";
        print "<input type=\"text\" size=\"30\" name=\"username\"><br>\n";
        print "<input type=\"submit\" name=\"soshin\" value=\"send\">\n";
        print "</form>\n";
    } else {
        print $yourname . " さん,こんにちは<br><br>";
        print "もう一度試しますか?<br>\n";
        print "<form method=\"get\">\n";
        print "<input type=\"submit\" name=\"soshin\" value=\"try again\">\n";
        print "</form>\n";
    }
?>

</body>
</html>

ブラウザから「http://localhost/yourname_GetVer.php」とURLを入力してページが表示されたとしよう。
名前欄に「TokyoTaro」と入れて,sendキーを押すと
「TokyoTaro さん,こんにちは」が表示されるであろう。ここまでの動作はpost版と同じである。
ところが,この段階でブラウザのURLをリクエストする欄には
「http://localhost/test/yournameGET.php?username=TokyoTaro&soshin=send」
が表示されている。
ここには「username」の名前で,「TokyoTaro」が送られ,「soshin」の名前で「send」が送られている様子が見えている。
それでは,「http://localhost/test/yournameGET.php?username=ABCDEFG&soshin=send」
と書いて送信すると,
「ABCDEFG さん,こんにちは」が表示される。
このように,getで送信すると,URL記述欄に何を送信したか表示されてしまう。
またページ上での作業とは無関係に適当な文字列をWebサーバに送りつけることができる。
簡単なデバッグや学習のためにはgetを使用するのも良いかもしれない。

名前欄に「東京 太郎」と入れて,sendキーを押すと
「東京 太郎 さん,こんにちは」が表示されるであろう。この段階でブラウザのURLをリクエストする欄には
「http://localhost/test/yournameGET.php?username=%E6%9D%B1%E4%BA%AC%E3%80%80%E5%A4%AA%E9%83%8E&soshin=send」
が表示されている。漢字は直接urlとして送信できないのでURLコーディングされ,送信される。




6.Webサーバ内でのファイルの読み書き(来訪者カウンタを作る)

phpプログラムはWebサーバ上で動いているので,ファイルの読み書きを行うというのは,
webサーバ上でのファイルの読み書きになる。ブラウザ側でのファイルの読み書きではない。
来訪者カウンタは,これまでの来訪人数を保存したcounter.txtをcounter.phpと同じディレクトリ
に置くと仮定すると次のように実現できる。ファイルの読み書きはC言語と同じくfopen-fclose
で囲んで,fgets,fputs,fseekなどが使える。

同時に複数の人が別なブラウザ(別のPC上の)から同じ操作をすると,
ファイルの読み書きに不都合が生ずるので,
本来はファイルの読み書きは排他制御をすべきである。

Table 6.1 来訪者カウンタ
PHPファイル (counter.php)
ブラウザでの表示
(http://localhost/counter.php)
<?php
    $fname = "counter.txt";
    if (file_exists($fname)) { //ファイルが存在したら
        $fp = fopen($fname, "r+");
        $count = fgets($fp, 64);
        fseek($fp, 0);
        $count++;
        fputs($fp, $count);
        fclose($fp);
    } else {
        $count = 1;
        $fp = fopen($fname, "w");
        fputs($fp, $count);
        fclose($fp);
    }
?>

<html>
<body>
あなたは
<?php
    print $count;
?>
人目の来訪者です。<BR>

</body>
</html>
あなたは 4 人目の来訪者です。



7.フォームによるアンケート(1)

フォームによるアンケートサイトを作成する。アンケート内容は,回答者のニックネーム,性別,好きな季節とする。
アンケート結果はファイルに保存することにする。
ここではフォームの部品として,ラジオボックスと
ポップアップリストを用いる。
フォームのアンケートはcsvファイルに追加書き込み保存することにする。
フォームによるアンケートを作成するためにはページの遷移をあらかじめよく考えておく必要がある。
基本的な繊維は,アンケート入力→入力の確認→結果の保存→保存の確認である。




ページ遷移部品は次のものが必要になる。(名前は自由につけられる)
トップページフォーム  送信ボタン(name="okuru")
プログラムが見にくくなるため,制御部と表示部を分けて書くとよい。
この考え方は将来MVC(Model View Controller モデル・ビュー・コントローラ)モデル
プログラミングにつながる。

Table 7.1 フォームによるアンケート(1)
<?php
//==== 制御部 ここから ====
    $sex[0]="男性";
    $sex[1]="女性";
    $season[0]="春";
    $season[1]="夏";
    $season[2]="秋";
    $season[3]="冬";
    $datafname="questionnaire.txt";
    if (isset($_POST['okuru']) == true) {
        $firsttime = false;
        $nickname=htmlspecialchars(
$_POST['nickname'], ENT_QUOTES);
        $seibetsu=$_POST['seibetsu'];
        $kisetsu=$_POST['kisetsu'];
        $fp=fopen($datafname,"a");
        fprintf($fp,"%s,%s,%s\r\n",$nickname,$sex[$seibetsu],$season[$kisetsu]);
        fclose($fp);
    } else {
        $firsttime = true;
    }
//==== 制御部 ここまで ====
?>

<html>
<body>

<?php
//==== 表示部 ここから ====
    if ($firsttime == true) {
        print "<h2>アンケートです</h2>\n";
        print "<form method=\"post\">\n";
        print "<b>1.あなたのニックネームは?</b>\n";
        print "<ul>\n";
        print "<input type=\"text\" size=\"30\" name=\"nickname\" required><br>\n";
        print "</ul>\n";
       
        print "<b>2.あなたの性別は?</b>\n";
        print "<ul>\n";
        print "<input type=\"radio\" name=\"seibetsu\" value=0 required>男性<br>\n";
        print "<input type=\"radio\" name=\"seibetsu\" value=1 required>女性<br>\n";
        print "</ul>\n";
       
        print "<b>3.あなたの一番好きな季節は?</b>\n";
        print "<ul>\n";
        print "<select name=\"kisetsu\">\n";
        print "<option value=0>春</option>";
        print "<option value=1>夏</option>";
        print "<option value=2>秋</option>";
        print "<option value=3>冬</option>\n";
        print "</select>";
        print "</ul>\n";

        print "回答がおわったら送信ボタンを押してください<br>\n";
        print "<ul>\n";
        print "<input type=\"submit\" name=\"okuru\" value=\"送信\">\n";
        print "</ul>\n";
        print "</form>\n";

    } else {
        print $nickname . " さんの回答です<br><br>";
        print "性別    : ".$sex[$seibetsu]."<br>\n";
        print "好きな季節 : ".$season[$kisetsu]."<br>\n";
        print "<br>\n";
        print "ファイル ".$datafname." に保存しました\n";
    }
//==== 表示部 ここまで ====
?>

</body>
</html>
アンケートページの表示
アンケートです

1.あなたのニックネームは?
2.あなたの性別は?
    男性
    女性
3.あなたの一番好きな季節は?
回答がおわったら送信ボタンを押してください


確認ページの表示
赤毛の子ぶた さんの回答です

性別    : 男性
好きな季節 : 夏

ファイル questionnaire.txt に保存しました

データ保存ファイル questionnaire.txt
トンボのメガネ,女性,秋
赤毛の子ぶた,男性,夏


required属性を与えているので,ニックネームと性別が未入力のときは,送信できないはずだが,
古いWebブラウザを使っている場合,エラーチェックが入っていないので,ラジオボタン無選択で
送信ボタンを押すとエラーになる。

見落としてはならないこと(再掲)
ここで行なったことはフォーム送信であり,<form>と</form>で囲まれた中に送りたい内容を書く。
type="submit"になっているボタンを押すことで,<form>と</form>で囲まれた中のデータを送信する。
送信されるデータは箱に入っており,その箱にはname=""で指定された名前が付いている。





8.フォームによるアンケート(2)


「7」で作成したアンケートは不親切で実用的でない。
保存してから保存確認と言われてもユーザが入力ミスをしている場合には困ってしまう。
入力確認段階で入力をすべて破棄して最初からやり直したい場合や,一部だけ変更したい場合がある。
また保存の確認を終えたら,次の人がアンケート入力できるようにしておきたい。
不完全な回答については再入力を求めることもしたい。



ページ遷移部品は次のものが必要になる。名前は自由につけられる
トップページフォーム  送信ボタン(name="okuru")
入力確認ページフォーム 確定保存ボタン(name="hozon") キャンセルボタン(name="kyanseru")
            やりなおし訂正ボタン(name="teisei")
保存確認ページ     了解ボタン(name="ryokai")

注意しなければならない点は,入力確認ページから別のページに移動する際に,
得られている回答データを持っていかなければならないことである。
このとき,フォーム部品の
<input type="hidden" ・・・>
を使う。ページ上には何も表示されていないけれど,フォームのデータとして,ページ移動の際に
それらの値を持っていくことができる。

Table 8.1 フォームによるアンケート(2)
<?php
//==== 制御部 ここから ====
    $sex[0]="男性";
    $sex[1]="女性";
    $season[0]="春";
    $season[1]="夏";
    $season[2]="秋";
    $season[3]="冬";
    $datafname="questionnaire.txt";
    $pageToDisplay=0; //表示すべきページ
    $nickname="";
    $seibetsu=-1; //どこも指していない状態
    $kisetsu=-1;  //どこも指していない状態
    $checkmessage="";
    if (isset($_POST['okuru']) == true) {
        $pageToDisplay=1;
        $kisetsu=$_POST['kisetsu'];
        if (isset($_POST['seibetsu'])) {
            $seibetsu=$_POST['seibetsu'];
        } else {
            $pageToDisplay=0;
            $checkmessage.="性別が選択されていません。<br>";
        }
        if ($_POST['nickname']!="") {
            $nickname=htmlspecialchars($_POST['nickname'], ENT_QUOTES);
        } else {
            $pageToDisplay=0;
            $checkmessage.="ニックネームが記入されていません。<br>";
        }
        if ($checkmessage!="") {
            $checkmessage="<font color=\"red\"><b>".$checkmessage;
            $checkmessage.="正しく記入してもう一度送信してください。</b></font><br>& lt;br>";
        }
    }
    if (isset($_POST['teisei']) == true) {
        $kisetsu=$_POST['kisetsu'];
        $seibetsu=$_POST['seibetsu'];
        $nickname=$_POST['nickname'];
    }
    if (isset($_POST['hozon']) == true) {
        $kisetsu=$_POST['kisetsu'];
        $seibetsu=$_POST['seibetsu'];
        $nickname=$_POST['nickname'];
        $pageToDisplay=2;
        $fp=fopen($datafname,"a");
        fprintf($fp,"%s,%s,%s\r\n",$nickname,$sex[$seibetsu],$season[$kisetsu]);
        fclose($fp);
    }
//==== 制御部 ここまで ====
?>

<html>
<body>

<?php
//==== 表示部 ここから ====
    if ($pageToDisplay == 0) {
        print "<h2>アンケートです</h2>\n";
        if ($checkmessage!="") print $checkmessage."\n";
        print "<form method=\"post\">\n";
        print "<b>1.あなたのニックネームは?</b>\n";
        print "<ul>";
        print "<input type=\"text\" size=\"30\" name=\"nickname\" value=\"".$nickname."\" required><br>\n";
        print "</ul>";
       
        print "<b>2.あなたの性別は?</b>\n";
        print "<ul>\n";
        for ($i=0; $i<2; $i++) {
            print "<input type=\"radio\" name=\"seibetsu\" value=".$i;
            if ($i==$seibetsu) print " checked";
            print " required>".$sex[$i]."<br>\n";
        }
        print "</ul>\n";
       
        print "<b>3.あなたの一番好きな季節は?</b>\n";
        print "<ul>\n";
        print "<select name=\"kisetsu\">\n";
        for ($i=0; $i<4; $i++) {
            print "<option value=".$i;
            if ($i==$kisetsu) print " selected";
            print ">".$season[$i]."</option>";
        }
        print "\n";
        print "</select>";
        print "</ul>\n";

        print "回答がおわったら送信ボタンを押してください。<br>\n";
        print "<ul>\n";
        print "<input type=\"submit\" name=\"okuru\" value=\"送信\">\n";
        print "</ul>\n";
        print "</form>\n";

    } else if ($pageToDisplay == 1) {
        print $nickname . " さんの回答です。<br><br>";
        print "性別    : ".$sex[$seibetsu]."<br>\n";
        print "好きな季節 : ".$season[$kisetsu]."<br>\n";
        print "<br>\n";
        print "<ul>\n";
        print "<form method=\"post\">\n";
        print "<input type=\"submit\" name=\"hozon\" value=\"確定送信\"><br>\n";
        print "<input type=\"hidden\" name=\"nickname\" value=\"".$nickname."\">\n";
        print "<input type=\"hidden\" name=\"seibetsu\" value=\"".$seibetsu."\">\n";
        print "<input type=\"hidden\" name=\"kisetsu\" value=\"".$kisetsu."\">\n";
        print "</form>\n";
        print "<form method=\"post\">\n";
        print "<input type=\"submit\" name=\"kyanseru\" value=\"キャンセル\"><br>\n";
        print "</form>\n";
        print "<form method=\"post\">\n";
        print "<input type=\"submit\" name=\"teisei\" value=\"やりなおし訂正\"><br>\n";
        print "<input type=\"hidden\" name=\"nickname\" value=\"".$nickname."\">\n";
        print "<input type=\"hidden\" name=\"seibetsu\" value=\"".$seibetsu."\">\n";
        print "<input type=\"hidden\" name=\"kisetsu\" value=\"".$kisetsu."\">\n";
        print "</form>\n";
        print "</ul>\n";
    } else if ($pageToDisplay == 2) {
        print "ファイル ".$datafname." に保存しました。<br><br>\n";
        print "<form method=\"post\">\n";
        print "<input type=\"submit\" name=\"ryokai\" value=\"了解\"><br>\n";
        print "</form>\n";
    }
//==== 表示部 ここまで ====
?>

</body>
</html>
アンケートページの表示
アンケートです

1.あなたのニックネームは?
2.あなたの性別は?
    男性
    女性
3.あなたの一番好きな季節は?
回答がおわったら送信ボタンを押してください。


入力データ確認ページ
ミルフィーユ さんの回答です。

性別   : 女性
好きな季節: 冬



保存確認ページ
ファイル questionnaire.txt に保存しました。




見落としてはならないこと(再掲)
ここで行なったことはフォーム送信であり,<form>と</form>で囲まれた中に送りたい内容が書かれて
いることを確認しよう。
type="submit"になっているボタンを押すことで,<form>と</form>で囲まれた中のデータが送信される。
送信されるデータは箱に入っており,その箱にはname=""で指定された名前が付いている。
当然だが,1つのフォーム内に同じ名前の箱が複数あってはならない。





他のフォーム部品を使ったアンケート例 questionnaire.html





9.フォームによるアンケートは自動生成するもの


「8」のようにすれば,いくらでもアンケートなどの情報収集ページを作ることができる。
しかし,毎回同じようなプログラムを作る羽目になる。
そこで,自動生成するプログラムをCで作成したものを紹介する。

QuestionnaireMaker.html




10.PHP基本要素



ここではPHPプログラム上の基本部品サンプルを紹介する。すべてのファイルは,htdocs内にあり,http://・・・としてブラウザから閲覧するものとする。
  1. ダイジェスト認証(MD5を使って暗号化してユーザID,パスワードを認証)
  2. WWWサーバからクライアントPCへのファイルのダウンロード
  3. クライアントPCからWWWサーバへファイルのアップロード
  4. WWWサーバでの排他的ファイル書き出し
  5. クッキーの利用
  6. セッションの利用

PHPProgramParts.html