ゼミII実習


ゼミIIで使用しているテキストがあります

動的Webページ作成(その10)PHPとMySQLの連携(その2)


今回はページのフォームよりデータをデータベースに追加する方法について考えてみましょう。

ところで、今回はデータベースにデータを追加するという操作が入るためセキュリティポリシーを強化する必要があります。しかし、ゼミでの実習においては実用面よりもその機能を実現することにポイントを置いています。

従って、データベースにアクセスしてデータベースに変更を加える場合にはログイン画面を用意しそこでユーザの認証を行った方がセキュリティを高めることになります。この機能を実現するには以下のような参考書を参考にして自分で試してみてください。

・PHP5逆引き大全500の極意、高島優作、秀和システム、2004、2600円

PHPについて基本から応用までのサンプルプログラムがたくさん掲載されています。ユーザの認証は第5章Webアプリケーションの極意で日記帳のところが参考になります。

・初めてのPHP5、David Sklar、桑村 潤、廣川 類 訳、オライリージャパン、2005、2800円

PHP5についての解説書です。サンプルコードが豊富に掲載されています。文法の解説から応用へと進んでいきます。第8章のクッキーとセッションでユーザを記憶のところにユーザ認証に関わる説明があります。

・PHP HACKS、Jack D. Herrington、牧野 聡 訳、オライリージャパン、2006、3600円

基本から枠を超えた利用法までコンパクトにまとめてあります。上記の2冊と異なる分野、グラフィックやデザインパターンなどの説明があり興味深いものとなっています。

それでは実習を進めていきますが、まずセキュリティポリシーについて考えておきましょう。

今回のMySQLとPHPの連携のシステムではまず次のようなセキュリティポリシーを取りたいと思います。

・MySQLのデータベースの作成、テーブルの作成はローカルホスト上で行う。ただしテーブルは設計だけとしデータの入力はユーザによりWebページ上から行われる。
・MySQLにユーザを登録し、そのユーザがPHP経由で特定のデータベースにアクセスできるようにする。
・ユーザはデータをデータベースに追加する。この時ユーザ認証は行わない。

以上のセキュリティポリシーの件は実習室のシステムにより勝手にユーザを作れないようになっています。そこで関係なくなりましたが参考のために削除しないでおきます。

それでは作業を進めていきましょう。

実習室のコンピュータは再起動後データベースが消えてしまいますので、前回ファイルを利用したデータベースの登録方法を使ってデータベースを作ってみましょう。

ただし、今回はテーブルはフィールドの情報を設定するだけで、データの入力はWebページを使って行います。

メモ帳などのテキストエディタを起動し、次のプログラムをコピーして貼り付けます。ファイル名はwcup2006_import3.sqlとしてHドライブに保存しておきましょう。

CREATE DATABASE wcup2006;
USE wcup2006;
CREATE TABLE entry (
  wgroup CHAR(1),
  country VARCHAR(50),
  flag CHAR(10)
);
SELECT * FROM entry;

スタート>すべてのプログラム>教材ツール>MySQLの順にクリックしてください。MySQLの画面がコマンドプロンプトを使用して現れます。

メッセージが表示された後で次のようなプロンプトが表示されています。

mysql>

このプログラムを試すために、次のSQL文を使用します。

source  h:\wcup2006_import3.sql

うまくいくと次のような表示が返されます。

Query OK, 1 row affected (0.00 sec)
Database changed
Query OK, 0 rows affected (0.17 sec)
Empty set (0.00 sec)

今回はデータベースwcup2006にテーブルentryが追加されました。表示に示されるようにテーブルentryにはデータが入っていないのでPHPを使ってこのテーブルにデータを入力していきましょう。

GRANT文は使用できないのでとばしてください。

その前にセキュリティポリシーに従いアクセスするためのユーザを用意します。

MySQLクライアントの画面で次の文を入力し、エンターキーを1回たたきます。

GRANT SELECT,INSERT ON wcup2006.* TO ba150999@localhost IDENTIFIED BY 'pekepeke';

実習室のシステムにより勝手にユーザを作れないようになっています。このコマンドは使えなくなりましたが、自分で環境を準備して勉強する場合には役に立つと思いますので削除しないでおきます。

GRANT文は新規にユーザを作成し権限を与えます。
SELECT,INSERTとしてSELECT文とINSERT文の使用の権限を与えています。
ONの次にデータベース名を指定しています。ここの設定ではデータベース名.テーブル名として設定します。この例ではデータベースwcup2006のすべてのテーブルにアクセスできます。
TOの次でユーザ名ba150999を与えています。@の次にホスト名を指定しています。
IDENTIFIED BYの次の’’で囲まれた文字列がパスワードになります。

うまくいった場合次のように表示されます。

Query OK, 0 rows affected (0.28 sec)

次にPHP経由でMySQLのデータベースwcup2006のテーブルentryにアクセスし、データを入力してみましょう。

まず、Apache Webサーバを起動してください。

スタート>すべてのプログラム>ネットワークツール>Apacheの順にクリックします。

タスクバー右下にApacheのアイコンが出ます。クリックして出てきたメニューでstartをクリックしてApacheサーバを起動します。

入力用の画面の設計を次の順で行っていきます。

まずフォームを使った入力画面をとりあえず作ってみます。このように本来の機能よりもアプリケーションの見かけから作り始めていくことをモックアップと呼んでいます。

メモ帳などのテキストエディタを起動し、次のプログラムをコピーして貼り付けます。ファイル名はwcup2006_input1.phpとしてHドライブに保存しておきましょう。

<?php
print <<<HTML_A
  <html>
  <head>
  <title>
  データ入力画面
  </title>
  </head>
HTML_A;
print <<<HTML_B
  <body>
  <br><br>
  <form method="POST">
  <table>
  <tr>
  <td>組</td>
  <td>
  <input type="text" name="kumi" maxlength="1">
  </td>
  </tr>
  <tr>
  <td>国名</td>
  <td>
  <input type="text" name="country" maxlength="50">
  </td>
  </tr>
  <tr>
  <td>ファイル名</td>
  <td>
  <input type="text" name="fname" maxlength="10">
  </td>
  </tr>
  <tr>
  <td colspan="2" align="right">
  <input type="submit" value="データベースに追加">
  </td>
  </tr>
  </table>
  </form>
  </body>
  </html>
HTML_B;
?>

C:¥Program Files¥Apache Group¥Apache2¥htdocsのフォルダにHドライブに今保存したwcup2006_input1.phpをコピーします。

インターネットエクスプローラを使って、次のURLで確認します。

http://localhost/wcup2006_input1.php

フォームを使用した入力画面が表示されます。

<注意>
たまにSyntax Errorで行末で$endがおかしい旨のエラーメッセージ(unexpected $end)が表示されることがあります。そのような場合にはプログラムの最後の行以降に余分な行を残さないで、プログラムの最後でファイルが終わるようにして試してみてください。

次のように<<<の次に続けて名前を書き、その名前と;ではさんだ部分はそのままデータとして扱えます。これをヒアドキュメントと呼んでいます。

print <<<HTML_A
  <html>
  <head>
  <title>
  データ入力画面
  </title>
  </head>
HTML_A;

ボタンをクリックしても何も動作しません。これからボタンをクリックした時にまず、入力したデータが画面に表示されるようにしてみましょう。

次のプログラムをwcup2006_input2.phpとしてC:¥Program Files¥Apache Group¥Apache2¥htdocsのフォルダに保存してください。

<?php
print <<<HTML_A
  <html>
  <head>
  <title>
  データ入力画面
  </title>
  </head>
HTML_A;
print <<<HTML_B
  <body>
  <br><br>
  <form method="POST" action="disp.php">
  <table>
  <tr>
  <td>組</td>
  <td>
  <input type="text" name="kumi" maxlength="1">
  </td>
  </tr>
  <tr>
  <td>国名</td>
  <td>
  <input type="text" name="country" maxlength="50">
  </td>
  </tr>
  <tr>
  <td>ファイル名</td>
  <td>
  <input type="text" name="fname" maxlength="10">
  </td>
  </tr>
  <tr>
  <td colspan="2" align="right">
  <input type="submit" value="データベースに追加">
  </td>
  </tr>
  </table>
  </form>
  </body>
  </html>
HTML_B;
?>

よく見比べてもらうとformタグのactionのところでdisp.phpと指定しているだけです。次にこのdisp.phpとして次のプログラムをC:¥Program Files¥Apache Group¥Apache2¥htdocsのフォルダに保存してください。

<?php
print "組".$_POST['kumi']."<br>";
print "国名".$_POST['country']."<br>";
print "ファイル名".$_POST['fname'];
?>

それからインターネットエクスプローラを使って、次のURLで確認します。

http://localhost/wcup2006_input2.php

入力欄で組にA(半角で入力します)、国名にドイツ、ファイル名にger_tn.pngを入力しボタンをクリックしてください。

入力されたデータがWebページとして出力されます。$_POST['kumi']のようにinputタグの属性nameの値と組み合わせて利用すればよさそうです。

それではボタンをクリックした時に入力したデータがデータベースに追加されるようにしてみましょう。

wcup2006_input2.phpのプログラムでformタグのところを次のように直してください。

  <form method="POST" action="dbase.php">

それからwcup2006_input3.phpとしてC:¥Program Files¥Apache Group¥Apache2¥htdocsのフォルダに保存してください。

次にこのdbase.phpとして次のプログラムをC:¥Program Files¥Apache Group¥Apache2¥htdocsのフォルダに保存してください。

実習室のシステムにより勝手にユーザを作れないようになっています。そこでやむを得ずユーザとしてroot、パスワードなしで行っています。実際にはセキュリティ上このような操作をしてはいけません。

<?php
  //コメントしてある部分はGRANT文でユーザを設定した場合です。
  //$db = mysql_connect("localhost", "ba150999", "pekepeke") 
  //      or die("接続できませんでした\n");
  $db = mysql_connect("localhost", "root", "") 
        or die("接続できませんでした\n");
        
  //MySQLの設定によりコメントした部分の設定が必要な場合があります。
  //実習室では以下のコメントしてあるプログラムは必要ありません。
  //mysql_query("SET NAMES sjis")
  //      or die("SET NAMES sjis の設定ができません");  
  mysql_select_db("wcup2006", $db)
        or die("該当するデータベースがないようです\n");
  $query = "INSERT INTO entry (wgroup, country, flag) "
           ."VALUES('"
           .$_POST['kumi']
           ."', '"
           .$_POST['country']
           ."', '"
           .$_POST['fname']
           ."')";
  $result = mysql_query($query, $db);
  //print $result;
  
  mysql_close($db);
?>

基本的に以前SELECT文を使用した時と同じ書き方です。今回は$queryに対して、INSERT INTO文を使用しているところが違います。この文を使って一行のデータ(レコード)を挿入することができます。

  $query = "INSERT INTO entry (wgroup, country, flag) "
           ."VALUES('"
           .$_POST['kumi']
           ."', '"
           .$_POST['country']
           ."', '"
           .$_POST['fname']
           ."')";

・INSERT INTO文の次にテーブル名entryを指定しています。
・その次の( )で使用するテーブルentryのフィールド名を並べます。
・それからVALUESで( )にレコードのデータをフィールドに対応させて与えてやります。文字列は’’で囲み、数値はそのまま記入します。
・この例ではわかりにくいのですが、文字列を.により結び付けてフォームから得られた値と結びつけています。
・例えば次のように書きたかったのですが(一行と見てください)

$query = "INSERT INTO entry (wgroup, country, flag) 
                   VALUES('A', 'ドイツ', 'ger_tn.png')";

フォームから得られた値と結びつけたので複雑になります。文字列の区切り方に注意しておきましょう。

それからインターネットエクスプローラを使って、次のURLで確認します。

http://localhost/wcup2006_input2.php

入力欄で組にA(半角で入力します)、国名にドイツ、ファイル名にger_tn.pngを入力しボタンをクリックしてください。

MySQLクライアントで

SELECT * FROM entry;

を入力してテーブルentryにレコードが追加されることを確認しましょう。

練習1.さて、ボタンを押した後、レコードがテーブルentryに追加されますが、Webページは何も表示されません。連続してレコードのデータを入力できるようにしてください。

練習2.もう一つボタンを用意し、現在のテーブルentryの中身を確認できるようにしてください。