5.PHP_MySQL3

前回の演習作業の続きを行う。

作業済みの以下のファイルを

レポートフォルダ → データベース演習2013(資料) → 第6回講義内容メモ

に置いたので、参考に利用してよい。

login.php

mypra_show.php

mypra_insert.php

mypra_delete.php

mypra_update.php

ログインページ

入力フォームの変数 $_REQUEST['password'] からパスワードを受け取り、チェックする。

正しいパスワードの場合、 セッション変数 $_SESSION["login"] の値 を "ok" とする。

ページを遷移しても、セッション変数の値を維持する為、セッション管理を行っている。

php スクリプトの先頭部分の session_start() コマンドでセッション管理が開始し、 session_destroy() を呼び出すことでセッションを終了し、

セッション変数の値を破棄できる。

login.php

<?php
session_start();
// 以下のコードでは、$_REQUEST['password'] の存在をチェックしいて
// パスワード未入力時のエラー表示を抑制している。
if(array_key_exists('password',$_REQUEST)) {

echo "パスワードが入力されました。<br>";

$password = $_REQUEST['password']; //入力フォームで入力された値の取り出し

} else {

echo "パスワードを入力してください。<br>";

$password = "";

}
// 上記はエラー抑制演算子@ を利用すると、以下の様にシンプルに記述できる。
// $password = @$_REQUEST['password'];
?>
<html>
<body>
<?php
if( $password == "1234" ) {

$_SESSION["login"] = "ok"; // ログイン成功のフラグとして セッション変数 loginに ok と記録

// mypra_show.php へ移動
?>
パスワード入力成功<br>
<br>
<a href="http://localhost/xampp/mypra_show.php">データ表示画面</a>
<?php
} else {

if($password != "")

{

echo "パスワードが一致しません。";

}

// ログインメッセージとパスワード入力欄を表示
?>
<h2>ログイン画面</h2>
<form action="login.php">
<input type="password" name="password"><br>
<input type="submit" value="送信">
</form>
<?php
}
?>
</body>
</html>

データ表示ページ

ログインのチェックをする。チェックに失敗の場合、ログインページへのリンクを表示する。

ログインに成功している場合、テーブルの全レコードを表示する。

mypra_show.php

<h1>練習データベース</h1>
<?php
session_start();
if(array_key_exists('login',$_SESSION)) {

$login = $_SESSION["login"]; //入力フォームで入力された値の取り出し

} else {

$login = "wrong";

}
if($login != "ok") {
?>
※ログインしてください※<br>
<a href="http://localhost/xampp/login.php">ログイン画面</a>
<?php
} else {

if(!mysql_connect("localhost","root",""))

{

echo "<h2>".$TEXT['cds-error']."</h2>";

die();

}

mysql_select_db("mypra");

mysql_query("SET NAMES utf8");

?>
<h2>プロフィール</h2>
<table border=0 cellpadding=0 cellspacing=0>
<tr bgcolor=#f87820>
<td><img src=img/blank.gif width=10 height=25></td>
<td class=tabhead><img src=img/blank.gif width=20 height=6><br><b>id</b></td>
<td class=tabhead><img src=img/blank.gif width=50 height=6><br><b>date</b></td>
<td class=tabhead><img src=img/blank.gif width=50 height=6><br><b>name</b></td>
<td class=tabhead><img src=img/blank.gif width=50 height=6><br><b>age</b></td>
<td class=tabhead><img src=img/blank.gif width=200 height=6><br><b>comment</b></td>
</tr>
<?php

$result=mysql_query("SELECT id,date,name,age,comment FROM mytest ORDER BY id;");


$i=0;

while( $row=mysql_fetch_array($result) )

{

if($i>0)

{

echo "<tr valign=bottom>";

echo "<td bgcolor=#ffffff background='img/strichel.gif' colspan=6><img src=img/blank.gif width=1 height=1></td>";

echo "</tr>";

}

echo "<tr valign=center>";

echo "<td class=tabval><img src=img/blank.gif width=10 height=20></td>";

echo "<td class=tabval><b>".htmlspecialchars($row['id'])."</b></td>";

echo "<td class=tabval>".htmlspecialchars($row['date'])."&nbsp;</td>";

echo "<td class=tabval>".htmlspecialchars($row['name'])."&nbsp;</td>";

echo "<td class=tabval>".htmlspecialchars($row['age'])."&nbsp;</td>";

echo "<td class=tabval>".htmlspecialchars($row['comment'])."&nbsp;</td>";

echo "<td class=tabval></td>";

echo "</tr>";

$i++;

}

echo "<tr valign=bottom>";

        echo "<td bgcolor=#fb7922 colspan=6><img src=img/blank.gif width=1 height=8></td>";
        echo "</tr>";
?>
</table>
<?php
}
?>
</body>
</html>

データ追加ページ

データ登録用フォームを表示し、入力&submit で 再び、mypra_insert.php を呼び出す。

呼び出し時に、名前欄に記入が有る場合、SQLでテーブルにデータを追加する。

追加したデータを PHP の echo コマンドで表示している。

問題点: 以下のSQLにはセキュリティ上の欠陥がある。

$result = mysql_query("INSERT INTO mytest (name,age,comment) VALUES('$name',$age,'$comment');");

$age を

$age=mysql_real_escape_string($_REQUEST['age']);

で、SQLインジェクション対策を施して、不正なSQLコードの入力を防いでいる。

しかし、 $age に、 id など テーブルのフィールド名として有効な文字列をセットすると、

MySQLは、idフィールドなどの値を、データベースに登録してしまう。

実際のシステムでは、mysql_real_escape_stringだけでなく、数値として解釈可能なデータが入力されたかどうかをチェックする必要がある。

mypra_insert.php

<h1>練習データベース</h1>
<?php

~セッション管理とログインチェックの部分省略~

mysql_query("SET NAMES utf8");

?>
<?php

if(@$_REQUEST['name']!="")

{

$name=mysql_real_escape_string($_REQUEST['name']);

$age=mysql_real_escape_string($_REQUEST['age']);

$comment=mysql_real_escape_string($_REQUEST['comment']);


$result = mysql_query("INSERT INTO mytest (name,age,comment) VALUES('$name',$age,'$comment');");

if(!$result) {

echo mysql_error();

}

echo "名前 ". $name ." / 年齢 ". $age . " / コメント " .$comment;

echo "<br>で登録しました。";

} else {

echo "名前を入力してください。";

}

?>
<h2>プロフィール登録</h2>
<form action=mypra_insert.php method=post>
<table border=0 cellpadding=0 cellspacing=0>
<tr><td>名前<td><input type=text size=30 name=name></td></tr>
<tr><td>年齢<td><input type=text size=30 name=age></td></tr>
<tr><td>コメント<td><input type=text size=30 name=comment></td></tr>
<tr><td></td><td><input type=submit border=0 value="登録"></td></tr>
</table>
</form>
<?php
}
?>
</body>
</html>

データ削除ページ

データ表示用ページとほぼ同じ構成。

テーブルのデータを一覧表示して、削除用のリンクを付け加える。

削除用のリンクには、action として del さらに、 id として、クリックしたレコードの id をQuery String として埋め込んでいる。

削除用リンクの基本構造:

<a href=mypra_delete.php?action=del&id=".$row['id'].">"削除"</a>

削除確認プロンプトのスクリプトや文字の装飾は省略。

mypra_delete.php

<h1>練習データベース</h1>
<?php
~セッション管理とログインチェックの部分省略~

mysql_query("SET NAMES utf8");

?>

~テーブルの見出し部分省略~

<?php

if(@$_REQUEST['action']=="del")

{

mysql_query("DELETE FROM mytest WHERE id=".round($_REQUEST['id']));

}

$result=mysql_query("SELECT id,date,name,age,comment FROM mytest ORDER BY id;");


$i=0;

while( $row=mysql_fetch_array($result) )

{

if($i>0)

{

echo "<tr valign=bottom>";

echo "<td bgcolor=#ffffff background='img/strichel.gif' colspan=6><img src=img/blank.gif width=1 height=1></td>";

echo "</tr>";

}

echo "<tr valign=center>";

echo "<td class=tabval><img src=img/blank.gif width=10 height=20></td>";

echo "<td class=tabval><b>".htmlspecialchars($row['id'])."</b></td>";

echo "<td class=tabval>".htmlspecialchars($row['date'])."&nbsp;</td>";

echo "<td class=tabval>".htmlspecialchars($row['name'])."&nbsp;</td>";

echo "<td class=tabval>".htmlspecialchars($row['age'])."&nbsp;</td>";

echo "<td class=tabval>".htmlspecialchars($row['comment'])."&nbsp;</td>";

echo "<td class=tabval><a onclick=\"return confirm('"."削除しますか?"."');\" href=mypra_delete.php?action=del&id=".$row['id']."><span class=red>["."削除"."]</span></a></td>";

echo "<td class=tabval></td>";

echo "</tr>";

$i++;

}

echo "<tr valign=bottom>";

        echo "<td bgcolor=#fb7922 colspan=6><img src=img/blank.gif width=1 height=8></td>";
        echo "</tr>";
?>
</table>
<?php
}
?>
</body>
</html>

データ修正ページ

データ削除用ページと同様の構成。

削除用リンクの代わりに、修正用リンクを表示する。

echo "<td class=tabval><a href=mypra_update.php?action=set&id=" .$row['id']. "><span class=red>[修正]</span></a></td>";

リンクには Query String として id と action を埋め込んでいる。
クリックした位置のレコードのid番号が id に、action は set に設定されている。
修正リンクをクリック後は、再び、 mypra_update.php を呼び出す。
action が set に設定されているので、データ修正用フォームが表示される。
修正対象のレコードを、

$result=mysql_query("SELECT id,date,name,age,comment FROM mytest WHERE id=" .$id. ";");

で id を元に検索し、修正前のデータを得ておく。
<tr><td>名前<td><input type=text size=30 name=name value="<?php echo $name ?>" ></td></tr>
の様に、データ修正用フォームに修正前の値を表示しておき、

<form action=mypra_update.php method=post>

<input type=hidden name=action value="update">
<input type=hidden name=id value=<?php echo $id; ?> >

データ修正用ホームに埋め込んだ hidden 属性の input タグで、 action として update 、 修正用 id として id を mypra_update.php に渡すようにする。

hidden属性のタグはWeb画面には表示されない。プログラムのデータ受け渡し用に用いるタグである。

修正データの送信方法を method=get による URLに埋め込まれた、Query Stinrg 方式から、 method=post によるPOST方式に変更している。

mypra_update.phpは、 action が update に設定されている場合、次のSQLコマンドにより、レコードを修正する。

$result = mysql_query("UPDATE mytest SET name='" .$name. "', age=" .$age. ", comment='" .$comment. "' WHERE id=" .$id. ";");

その後修正後のテーブルを一覧表示している。

mypra_update.php

<h1>練習データベース</h1>
<?php
~セッション管理とログインチェックの部分省略~

mysql_query("SET NAMES utf8");

if(@$_REQUEST['action']=="set")

{

$id = mysql_real_escape_string(@$_REQUEST["id"]);

$result=mysql_query("SELECT id,date,name,age,comment FROM mytest WHERE id=" .$id. ";");

$row=mysql_fetch_array($result);

$name = htmlspecialchars($row['name']);

$age = htmlspecialchars($row['age']);

$comment = htmlspecialchars($row['comment']);

?>
<h2>プロフィール修正</h2>
<form action=mypra_update.php method=post>
<input type=hidden name=action value="update">
<input type=hidden name=id value=<?php echo $id; ?> >
<table border=0 cellpadding=0 cellspacing=0>
<tr><td>名前<td><input type=text size=30 name=name value="<?php echo $name ?>" ></td></tr>
<tr><td>年齢<td><input type=text size=30 name=age value="<?php echo $age ?>"></td></tr>
<tr><td>コメント<td><input type=text size=30 name=comment value="<?php echo $comment ?>"></td></tr>
<tr><td></td><td><input type=submit border=0 value="修正"></td></tr>
</table>
</form>
<?php

} else {

?>

~テーブルの見出し部分省略~

<?php

if(@$_REQUEST['action']=="update")

{

$id=mysql_real_escape_string($_REQUEST['id']);

$name=mysql_real_escape_string($_REQUEST['name']);

$age=mysql_real_escape_string($_REQUEST['age']);

$comment=mysql_real_escape_string($_REQUEST['comment']);


$result = mysql_query("UPDATE mytest SET name='" .$name. "', age=" .$age. ", comment='" .$comment. "' WHERE id=" .$id. ";");

if(!$result) {

echo mysql_error();

}

echo "ID ". $id ." / 名前 ". $name ." / 年齢 ". $age . " / コメント " .$comment;

echo "<br>で修正登録しました。";

}

~テーブルの表示のループの部分省略~

echo "<td class=tabval><a href=mypra_update.php?action=set&id=" .$row['id']. "><span class=red>[修正]</span></a></td>";

echo "<td class=tabval></td>";

echo "</tr>";

$i++;

}

echo "<tr valign=bottom>";

echo "<td bgcolor=#fb7922 colspan=6><img src=img/blank.gif width=1 height=8></td>";

echo "</tr>";

?>
</table>
<?php

}

}
?>
</body>
</html>