簡易画像掲示板の構成とログイン
■作成する簡易画像掲示板の構成
単純なアップロード機能のみの簡易画像掲示板を作成します。
作成する簡易画像掲示板の主な機能です。
・あらかじめ登録されている4ユーザーだけがアクセス可能
・JPEG画像とメッセージのみがアップロード可能
・画像一覧をサムネイルで表示し、サムネイルをクリックすると元画像を表示
ようするに画像とメッセージをアップするだけの簡単なものです。画像の種類もJPEGに限定しています。
しかし2つのテーブルと6つのPHPスクリプトを含むそれなりに長いプログラムです。
次は今回作成する簡易画像掲示板の構成です。
x
■データベースとテーブルの構成
次はこの簡易画像掲示板で使うテーブルの内容です。データベースはすでに作成済みの「db」を使用します。
●テーブル「table1」
「table1」は、次のようなカラム構造になっており、投稿番号や画像ファイル名とメッセージなどを保存するメインテーブルです。
テーブル「table1」の構造
カラム名 | データ型 | 内容 |
ban | int | 投稿番号(連続番号機能) |
nam | varchar(128) | 投稿者の名前 |
mes | varchar(128) | メッセージ |
ope | int | 非公開なら「0」、公開なら「1」 |
gaz | varchar(64) | 画像ファイルの名前 |
dat | datetime | 投稿日時 |
●画像ファイルを保管するときのファイル名
アップロードされたファイルをWebサーバーに保存するとき、カラム「gaz」にはその画像ファイルの名前を保管します。この画像ファイルの名前は、処理した「年月日時分秒(date('YmdHis'))」に、アップロードしたときの「元のファイル名」を結合した文字列とします。
●サムネイル画像ファイルを保管するときのファイル名
サムネイル画像のファイルの名前は、保存した画像ファイル本体の名前に「xamp_」を付けた名前とします。たとえば、保管されるファイルの名前が「999999999abcdef.jpg」の場合、サムネイル画像のファイルの名前は「xamp_999999999abcdef.jpg」となります。
●テーブル「table2」
「table2」は、ユーザーの情報を格納するテーブルです。構造は、次のようになります。
テーブル「table2」の構造
カラム名 | データ型 | 内容 |
id | varchar(64) | ユーザー名 |
pas | varchar(64) | パスワード(md5で処理したものを保管) |
nam | varchar(128) | 会員氏名 |
このテーブルに以下のようなユーザーを登録します。
テーブル「table2」に登録するユーザー
id | pas | nam |
admin | himitunopass | tanaka |
user1 | inupass | dog |
user2 | nekopass | cat |
user3 | usagipass | rabbit |
カラム「pas」にはパスワードの情報を保管しますが、そのままのパスワード文字列ではありません。それぞれのパスワードの文字列を引数としてmd5関数で処理した値を、カラム「pas」に保管するものとします。
●簡易画像掲示板作成上の注意
画像掲示板では、Cookieとセッションを使用します。たとえばCookieをブロックする設定になっていると、認証されても画像掲示板を利用することはできません。
サンプルを利用するときは、Cookieを「受け入れる」か「ダイアログを表示する」の設定にしておいてください。
簡易画像掲示板の作成
では簡易画像掲示板を作成していきましょう。まずは、公開するディレクトリ(c:¥xampp¥htdocs)にgz_imgとgz_dataの2つのディレクトリを作成してください。
■テーブルの作成
テーブルを作成します。phpMyAdminを使用して、データベース「db」にテーブル「table1」と「table2」を作成します。なお、「table1」のカラム「ban」には必ず「連続番号機能」を設定してください。
次にユーザー情報テーブル「table2」に、ユーザー名とパスワードを登録しますが、これはphpMyAdminから行うことができません。なぜならカラム「pas」は、PHPのmd5関数でハッシュ値に変換してからテーブルに格納するからです。そこで、次のようなPHPスクリプトを作成して、実行してください。
g_user_make.php
<?php
$db = new pdo("mysql:host=localhost;dbname=db","root","");
$db->query("INSERT INTO table2(id,pas,nam)VALUES('admin',md5('himitunopass'),'tanaka')");
$db->query("INSERT INTO table2(id,pas,nam)VALUES('user1',md5('inupass'),'dog')");
$db->query("INSERT INTO table2(id,pas,nam)VALUES('user2',md5('nekopass'),'cat')");
$db->query
("INSERT INTO table2(Id,pas,nam)VALUES('user3',md5('usagipass'),'rabbit')");
print"<p>table2にユーザーを作成</p>";
?>
PDODESCデータベースへ接続し、INSERT文でレコードを挿入しているだけですが、カラム「pas」に格納されるデータの指定にmd5関数を使っています。上記はエラー処理などを行っていませんので、必ずphpMyAdminでレコードが挿入されているか確認してください。
レコードの確認
■ログイン処理
ではPHPスクリプトを作成していきましょう。これ以降gz_db_info.php以外のPHPスクリプトは、すべてドキュメントルート(c:¥xampp¥htdocs)に保存します。
最初はログインの仕組みです。次は、ユーザー名とパスワードを送信するログイン画面のHTMLです。それぞれ「user」「pass」の「データを識別する名前」でPOST送信します。
g_login.html
<HTML>
<HEAD>
<META HTTP EQUIV='Content-Type' CONTENT='text/html;charset=UTF-8'>
<TITLE>ログイン画面</TITLE>
<BODY>
<P STYLE='color: red'>ABC写真</P>
ログインしてください<br>
<FORM ACTION="g_logon2.php" METHOD="post">
ユーザ名<INPUT TYPE='text' NAME='user' SIZE ='30'><br>
パスワード<INPUT TYPE="password" NAME ="pass" SIZE ="30">
<INPUT TYPE ="submit" VALUE="送信">
</FORM>
</BODY>
</HTML>
ログイン画面
ここでは、送信するユーザー名とパスワードを入力するテキストボックスの「データを識別する名前」が、それぞれ「user」と「pass」であることを覚えておきます。
ログイン画面「g_login.html」からのユーザー名とパスワードのPOST送信を受けて、ユーザー認証をするのが次の「g_login2.php」です。
g_login2.php
<?php
session_start(); ①
$u =htmlspecialchars($_POST['user'],ENT_QUOTES); ②
$p =htmlspecialchars($_POST['pass'],ENT_QUOTES); ②
require_once("db_init.php"); ③
?>
<HTML>
<HEAD>
<META HTTP EQIV='Content-Type' CONTENT='text/html;charset=UTF-8'>
<TITLE>ようこそABC写真へ!</TITLE>
</HEAD>
<BODY>
<?php
$ps =$db->query("SELECT pas FROM table2 WHERE id='$u'"); ④
if ($ps->rowCount()>0){ ⑤
$r =$ps->fetch(); ⑥
if($r['pas']===md5($p)){ ⑦
$_SESSION['us']= $u; ⑧
?>
<P>ようこそABC写真へ!</P>
<P><A HREF='g.php'>ここをクリックして一覧表示へ</A></P> ⑨
<?php
}else{
session_destroy(); ⑩
?>
<P>パスワードが違います。<br>
<A HREF='g_login.html'>ログイン</A></P> ⑩
<?php
}
}else{
session_destroy();
?>
<P>ユーザーが登録されていません<br>
<A HREF='g_login.html'>ログイン画面へ</A></P> ⑪
<?php
}
?>
</BODY>
</HTML>
①session_start関数で、セッションを開始
g_login.htmlで送信された「ユーザー名」と「パスワード」の「データを識別す名前
はそれぞれ「user」および「pass」です。
②それぞれを$_POST['user']および$_POST['pass']でPOST送信で受け取ったデータをさらにhtmlspecialcharsでタグを無効化します。
最終的にユーザー名は変数$uに、パスワードは変数$pに代入します。
$u =htmlspecialchars($_POST['user'],ENT_QUOTES);
$p =htmlspecialchars($_POST['pass'],ENT_QUOTES);
③データベース初期化ファイル「db_init.php」をrequire_onceで読み込みデータベースを初期化します。
④PDOのqueryメソッドで、SELECT文を実行し、変数$psに代入。
オブジェクト変数$dbでデータベースを読み込む。
$ps =$db->query("SELECT pas FROM table2 WHERE id='$u' ");
カラム「id」が$u(ユーザー名)であることを条件にして、table2の一致するレコードのカラム「pas」に保管されている文字列(パスワード文字をmd5で処理した文字)を検索します。queryメソッドが返すデータは(クエリの結果)は、変数$psに代入しています。
⑤if文で、登録ユーザーかどうかを判断
if ($ps->rowCount()>0){
PDOStatementのrowCountメソッドは結果の行数を返します。これが0より大きければ(id='$u'が存在)登録されたユーザーであると判断、そうでなければ送信されたユーザー名が登録されていないと判断します。もし、この条件にFALSEが返された場合は、session_destory関数でセッションを破棄して、ログインへのリンク(A HREF='g_login.html'>を表示します⑪。
⑥PDOStatementのfetchメソッドによりレコードを取り出し、$rに格納。
⑦teble2の「pas」カラムの値と入力したパスワードの値が正しいかどうかをチェック
if($r['pas']===md5($p)){
===(厳密等価演算子)「右側の値と左側の値は、変数の型(変数の種類)まで含めて同じですか~?」な比較を意味する演算子
md5($p)は送信されてきたユーザー名($p)をmd5で処理したもので、これがユーザー名から検索されたカラム「pas」の値と一致すれば、ユーザー名とパスワードの組み合わせは正しいと判断します。
⑧セッション変数「us」にユーザー名($u)を代入
⑨一覧へのリンク(<A HREF='g.php'>)を表示します。
⑩パスワードが一致しない場合は、セッションを破棄した後、ログインへのリンクを
表示します。
実行結果
ユーザーが登録されていない場合
パスワードが違う場合