スレッド表示 | フラット表示〕 全トピック 920 件中 128 番目 次≫ ≪前

みなさん、ご面倒をおかけしました。

created: 2007-03-20 18:05 | modified: 2007-03-23 18:44 | reply: 6

[3670] みなさん、ご面倒をおかけしました。

user: PHP勉強野郎! | created: 2007-03-20 18:05
ゆうじさん、achさん、YOSHIさん、ご面倒おかけしました。

おかげ様で一応自分の望む…
・トップページで『ID』『PASS』の入力、なければ『登録ページ』で新規登録 ※重複登録のチェック
・トップページで退会を選べば、『ID』『PASS』をチェックして
退会処理
・トップページで『ID』『PASS』を入力してログインすれば
会員ページへ
・日毎の登録者数と退会者数の確認が出来る
と以上の事が出来るページが出来ました。

乱雑なコードですが、読んでくださる方がいれば幸いです。
その際、よければ駄目出しや気をつけた方が良い点などが
あれば更なるご指導賜りたいと思っております。
よろしくお願いします。

・トップページ
<?php
// PHP開始
$id = htmlspecialchars($_POST['id'], ENT_QUOTES); // クオートの変換(特殊文字を HTML エンティティに変換する
$pass = htmlspecialchars($_POST['passwd'], ENT_QUOTES); // クオートの変換(特殊文字を HTML エンティティに変換する
$sec_id = htmlspecialchars($_POST['sec_id'], ENT_QUOTES); // クオートの変換(特殊文字を HTML エンティティに変換する
$sec_pass = htmlspecialchars($_POST['sec_passwd'], ENT_QUOTES); // クオートの変換(特殊文字を HTML エンティティに変換する

$connect = pg_Connect("user='yuuji' dbname='database'");
// データベースに接続する
if ($connect == 0) // 接続IDが帰ってこなかったら
{
exit(); // 終了する
}
$result = pg_query($connect, "SELECT * FROM test WHERE id = '$id' AND pass = '$pass'");
// フォームから入力された値を条件にデータベースから『id』と『pass』の内容を取得・変数$resultに格納する
$num = pg_numrows($result);
// データベースの行数を取得
if($num) { // TRUEの時
$url = "http://192.168.0.22/~yuuji/kadai/kadai/member.php"; // 指定URL
header('Location: '. $url); // HTTPヘッダを送信する
exit(); // メッセージを出力し、カレントのスクリプトを終了する
}
// PHP終了
?>
<!DOCTYPE html PUBLIC "-W3C//DTD HTML 4.01 Transitional//EN">
<HTML lang = "ja">
<HEAD>
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=euc-jp">
<TITLE>トップページ</TITLE>
</HEAD>
<BODY>
<H1>トップページ</H1>
<PRE>
<FORM action = "top.php" method = "POST">
ID :<INPUT type = "text" name = "id" size = "20">
PASS:<INPUT type = "text" name = "passwd" size = "20">
<INPUT type = "submit" value = "ログイン">  会員登録をしていない方は<A href = "regist.php">入会登録</A>
</FORM>
<FORM action = "top.php" method = "POST">
ID :<INPUT type = "text" name = "sec_id" size = "20">
PASS:<INPUT type = "text" name = "sec_passwd" size = "20">
<INPUT type = "submit" value = "退会">
</FORM></PRE>
<CENTER>
<TABLE border=2>
<TR><TH>ID</TH><TH>PASS</TH><TH>NAME</TH><TH>REG</TH><TH>SEC</TH><TH>STATE</TH></TR>
<?php
if($sec_id == '' OR $sec_pass == '') // ID・PASSが空白ならば
{
echo "<BR><CENTER>IDとPASSを入力して下さい (^o^)/</CENTER></BR>";
$result = pg_query($connect, "SELECT * from test");
// データベースの全内容を取得・変数$resultに格納する
} else {
$query = pg_query($connect, "SELECT id, pass FROM test WHERE id = '$sec_id' AND pass = '$sec_pass'");
// データベースからの取り出し・フォームから入力された値を取り出し
$query_num = pg_numrows($query);
// // データベースの行数を取得
if($query_num >= 1) // データベースから取り出した行数が一行の時
{
$delete = pg_query($connect, "UPDATE test SET sec = 'now', state = 0 WHERE id = '$sec_id' AND pass = '$sec_pass'");
if($delete) {
echo "<BR><CENTER>このIDを削除しました。</CENTR><BR>";
pg_query($connect, "UPDATE test SET pass = '' WHERE id = '$sec_id'");
}
}
}
$result = pg_query($connect, "SELECT * FROM test");

for($i = 0; $i < $num; $i++) // 変数iがnum以下のとき
{
$id = pg_fetch_result($result, $i, 'id'); // データベースのi行目の0列目を取得し変数に格納する
$pass = pg_fetch_result($result, $i, 'pass'); // データベースのi行目の1列目を取得し、変数に格納する
$name = pg_fetch_result($result, $i, 'name'); // データベースのi行目の1列目を取得し、変数に格納する
$reg = pg_fetch_result($result, $i, 'reg'); // データベースのi行目の1列目を取得し、変数に格納する
$sec = pg_fetch_result($result, $i, 'sec'); // データベースのi行目の1列目を取得し、変数に格納する
$state = pg_fetch_result($result, $i, 'state'); // データベースのi行目の1列目を取得し、変数に格納する

print("<TR ALIGN = RIGHT><TD>$id</TD><TD>$pass</TD><TD>$name</TD><TD>$reg</TD><TD>$sec</TD><TD>$state</TD></TR>");
// テーブルの中に表示する
}
pg_close($connect);
// データベースとの接続を閉じる
?>
</TABLE><BR><BR>
</CENTER></BODY></HTML>


・登録ページ
<!DOCTYPE html PUBLIC "-W3C//DTD HTML 4.01 Transitional//EN">
<HTML lang = "ja">
<HEAD>
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=euc-jp">
<TITLE>会員登録ページ</TITLE>
</HEAD>
<BODY>
<CENTER>
<H1>会員登録ページ</H1>
<PRE>
<FORM action = "<?php $_SERVER['PHP_SELF']?>" method = "POST">
ID :<INPUT type = "text" name = "id" size = "20"><BR>
PASS:<INPUT type = "text" name = "passwd" size = "20"><BR>
NAME:<INPUT type = "text" name = "name" size = "20"><BR>
<INPUT type = "submit" value = "登録">
</FORM></PRE>
<TABLE border=2>
<TR><TH>ID</TH><TH>PASS</TH><TH>NAME</TH><TH>REG</TH><TH>SEC</TH><TH>STATE</TH></TR>
<?php
// PHP開始
$id = htmlspecialchars($_POST['id'], ENT_QUOTES); // クオートの変換(特殊文字を HTML エンティティに変換する
$pass = htmlspecialchars($_POST['passwd'], ENT_QUOTES); // クオートの変換(特殊文字を HTML エンティティに変換する
$name = htmlspecialchars($_POST['name'], ENT_QUOTES); // クオートの変換(特殊文字を HTML エンティティに変換する

$connect = pg_Connect("user='yuuji' dbname='database'");
// データベースに接続する
if ($connect == 0) // 接続IDが帰ってこなかったら
{
exit(); // 終了する
}
if($id == '' OR $pass == '' OR $name == '')
{
$result = pg_query($connect, "SELECT * from test");
// データベースの全内容を取得・変数$resultに格納する
} else {
$query = pg_query($connect, "SELECT id FROM test WHERE id = '$id'");
// データベースから入力された『ID』の値を取り出す
$query_num = pg_numrows($query);
// 取り出した『ID』の抽出件数を調べる
if($query_num) // 問い合わせて結果が帰ってきたとき
{
for($j = 0; $j < $query_num; $j++) // 変数iがnum以下のとき
{
echo "<BR><CENTER>このIDは既に使われています。</CENTER>";
}
} elseif(!$query_num) { // // 問い合わせて結果が無かったとき
echo "<BR><CENTER>このIDを新規登録します。</CENTER>";
pg_query($connect, "INSERT INTO test(id, pass, name, reg, state) VALUES('$id', '$pass', '$name', 'now', 1)");
// 『ID』『PASS』『NAME』『REG』『STATE』を挿入する
}
}

$result = pg_query($connect, "SELECT * FROM test");
$num = pg_numrows($result);
// データベースの行数を取得
for($i = 0; $i < $num; $i++) // 変数iがnum以下のとき
{
$id = pg_fetch_result($result, $i, 'id'); // データベースのi行目の0番目を変数に格納する
$pass = pg_fetch_result($result, $i, 'pass'); // データベースのi行目の1番目の変数に格納する
$name = pg_fetch_result($result, $i, 'name'); // データベースのi行目の1番目の変数に格納する
$reg = pg_fetch_result($result, $i, 'reg'); // データベースのi行目の1番目の変数に格納する
$sec = pg_fetch_result($result, $i, 'sec'); // データベースのi行目の1番目の変数に格納する
$state = pg_fetch_result($result, $i, 'state'); // データベースのi行目の1番目の変数に格納する

print("<TR ALIGN = RIGHT><TD>$id</TD><TD>$pass</TD><TD>$name</TD><TD>$reg</TD><TD>$sec</TD><TD>$state</TD><TR>"); // テーブルの中に表示する}
}
pg_close($connect);
// データベースとの接続を閉じる
// PHP終了
?>
</TABLE><BR><BR>
<A href = "top.php">戻る</A></CENTER>
</BODY></HTML>

・会員ページ
<!DOCTYPE html PUBLIC "-W3C//DTD HTML 4.01 Transitional//EN">
<HTML lang = "ja">
<HEAD>
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=euc-jp">
<TITLE>会員ページ</TITLE>
</HEAD>
<BODY>
<CENTER>
<H1>会員ページ</H1>
<BR><BR>
<TABLE border=2>
<TR><TH>ID</TH><TH>PASS</TH><TH>NAME</TH><TH>REG</TH><TH>SEC</TH><TH>STATE</TH></TR>

<?php
// PHP開始
$connect = pg_Connect("user='yuuji' dbname='database'");
// データベースに接続する
if ($connect == 0) // 接続IDが帰ってこなかったら
{
exit(); // 終了する
}
$result = pg_query($connect, "SELECT * FROM test");
// データベースの全内容を取得・変数$resultに格納する
$num = pg_numrows($result);
// データベースの行数を取得
for($i = 0; $i < $num; $i++) // 変数iがnum以下のとき
{
$id = pg_result($result, $i, 0); // データベースのi行目の0番目を変数に格納する
$pass = pg_result($result, $i, 1); // データベースのi行目の1番目の変数に格納する
$name = pg_result($result, $i, 2); // データベースのi行目の1番目の変数に格納する
$reg = pg_result($result, $i, 3); // データベースのi行目の1番目の変数に格納する
$sec = pg_result($result, $i, 4); // データベースのi行目の1番目の変数に格納する
$state = pg_result($result, $i, 5); // データベースのi行目の1番目の変数に格納する

print("<TR ALIGN = RIGHT><TD>$id</TD><TD>$pass</TD><TD>$name</TD><TD>$reg</TD><TD>$sec</TD><TD>$state</TD><TR>");
// テーブルの中に表示する
}
// PHP終了
?>
</TABLE><BR><BR>
<TABLE><TR><TH><TABLE border = 1>
<TR><TH>登録日</TH><TH>登録数</TH></TR>
<?php
$reg = pg_query($connect, "SELECT TO_CHAR(reg, 'yyyy年mm月dd日') AS time, COUNT(*) AS reg FROM test GROUP BY time ORDER BY time");
// 登録年月日を抽出し登録年月日で集計し、登録年月日でまとめる。登録年月日順に並び替える
$num = pg_numrows($reg);
// データベースの行数を取得
for($i = 0; $i < $num; $i++) // 変数iがnum以下のとき
{
$regist_time = pg_fetch_result($reg, $i, 'time'); // データベースのi行目の0列目を取得し変数に格納する
$regist_num = pg_fetch_result($reg, $i, 'reg'); // データベースのi行目の1列目を取得し、変数に格納する

print("<TR ALIGN = RIGHT><TD>$regist_time</TD><TD>$regist_num</TD></TR>"); // テーブルの中に表示する}
}
?>
</TABLE></TH>
<TH><TABLE border = 1>
<TR><TH>退会日</TH><TH>退会数</TH></TR>
<?php

$sec = pg_query($connect, "SELECT TO_CHAR(sec, 'yyyy年mm月dd日') AS time, COUNT(*) AS sec FROM test WHERE state = 0 GROUP BY state , time ORDER BY time");
// 退会年月日を抽出し退会年月日で集計し、退会年月日でまとめる。退会年月日順に並び替える
$num = pg_numrows($sec);
// $secの行数を取得
if($num) {
for($i = 0; $i < $num; $i++) // 変数iがnum以下のとき
{
$release_time = pg_fetch_result($sec, $i, 'time'); // データベースのi行目の0列目を取得し変数に格納する
$release_num = pg_fetch_result($sec, $i, 'sec'); // データベースのi行目の1列目を取得し、変数に格納する
print("<TR ALIGN = RIGHT><TD>$release_time</TD><TD>$release_num</TD></TR>");
// テーブルの中に表示する
}
}
pg_close($connect);
// データベースとの接続を閉じる
?>
</TABLE></TH></TR></TABLE><BR><BR>
<A href = "top.php">戻る</A></CENTER>
</BODY></HTML>

自分の納得出来ない点はデータベースから文字列を取り出して
フォームから入力したデータと比較する際にSQLで『rtrim』を
しなければ正常に文字列が抜き出せず、比較が出来なかった事
です。対処方法をご存知のかた、ご教授お願いします。
reply: 3672 3679 返信 編集 削除

[3672] Re.みなさん、ご面倒をおかけしました。

user: さとし | created: 2007-03-20 20:48
初めまして。
最近PHPに限らずWEBアプリはセキュリティが大変だと感じております。

ざっと読んでみた感じ、事前のチェックが甘い様に思います。
登録の際、IDにスペースが入っても通ってしまいます。
(チェック済みならごめんなさい。)
あと、$_POSTには色々な物が入ります。
よそから配列にされる可能性もありますし、携帯だと改行も入れられます。

作り始めより段々コードが増えていく場合が多いので、HTMLと肝の処理は分離した方が把握しやすくなります。
pg_なんちゃらを含む処理とHTMLでファイルを分けると美しくなります。
Parent: 3670  reply: 3674 返信 編集 削除

[3674] お返事ありがとうございます♪

user: PHP勉強野郎! | created: 2007-03-21 23:28
さとしさん、お返事ありがとうございました。

>ざっと読んでみた感じ、事前のチェックが甘い様に思います
>登録の際、IDにスペースが入っても通ってしまいます。
>あと、$_POSTには色々な物が入ります。
>よそから配列にされる可能性もありますし、携帯だと改行も>入れられます。

そぅですか…(>_<)
現状は現状では抽出された行があるか? ないか? で
判断している状況なので、文字での比較をしていません。
内容を取得して空白が入っていたら空白を削除する処理などを入れてやる事を考えたほうがいいのでしょうか?
あと、『配列にされる可能性がある』『携帯だと改行を入れられる』とありますが、どういう事なのでしょうか?
自分はGETとPOSTの使用意図を理解しておらず、すべてPOSTで行えばよいと思っているので、詳しく解りません。

>HTMLと肝の処理は分離した方が把握しやすくなります。
>pg_を含む処理とHTMLでファイルを分けると美しくなりま
>す。

分離したほうが…とありますが、具体的にはどのようにすれば宜しいのでしょうか?
再度の質問となりますが教えて頂けないでしょうか?
Parent: 3672  reply: 3675 返信 編集 削除

[3675] Re.お返事ありがとうございます♪

user: さとし | created: 2007-03-22 00:45
こんばんは。

> 現状は現状では抽出された行があるか?で
> 判断している状況なので、文字での比較をしていません。
> 内容を取得して空白が入っていたら空白を削除する処理な
> どを入れてやる事を考えたほうがいいのでしょうか?
例えば郵便番号なんかでしたら、全角を半角へ変換してから登録するような、やさしい作りにできますけど、後で認証に使うIDはそうはいきません。キーボードで打ったIDとサーバのIDが一致しないと困ります。
こんな感じで半角英数字以外はお断りにするといいかも。
$id = $_POST['id'];
if(!preg_match('/^[A-Z0-9]{4,12}$/i', $id)) {
echo 'IDは半角英数字4~12文字で入力してね。';
}
こうした場合、IDが制限されるので、htmlspecial~しなくて済みます。

> あと、『配列にされる可能性がある』『携帯だと改行を入れられる』とありますが、どういう事なのでしょうか?
先のIDのように事前にチェックしておけば、はじかれますので。

> >HTMLと肝の処理は分離した方が把握しやすくなります。
> 具体的にはどのようにすれば宜しいのでしょうか?
なんかいっぺんに言って分かりにくかったですね。
あれこれモードが増えていった場合、ファイルを分散させないときつくなってきます。
例えば、登録フォームを表示させる場合は一切PHPはいらないですよね。IDが送信された時に別ファイルのPHPに処理させる様にしておくとスマートになります。
これぐらいの規模ならそのままでもいいと思います。
Parent: 3674  reply: 3678 返信 編集 削除

[3678] どうもありがとうございます。

user: PHP勉強野郎! | created: 2007-03-22 16:56
ご教授ありがとうございます。

解らないことばかりですが、これからも日々精進していきたいと
思っております。
どうもありがとうございました。
Parent: 3675  返信 編集 削除

[3679] RE:トップページ

user: YOSHI | created: 2007-03-22 23:07
すみません。もう決着されたのかも知れませんが。

斜め読みなので私の理解が足りないのか、

・トップページ
<?php
// PHP開始
$id = htmlspecialchars($_POST['id'], ENT_QUOTES);

-- snip

この時点で、

Notice: Undefined index: id in トップページ が出て、

$id = 0;
$pass = 0;
$sec_id = 0;
$sec_pass = 0;
と初期化され、クエリは、
$result = pg_query($connect, "SELECT * FROM test WHERE id = '0' AND pass = '0'");
となり、ほぼ100% header('Location: '. $url); へ飛んでしまい、

// PHP終了?>
<!DOCTYPE html PUBLIC "-W3C//DTD HTML 4.01 Transitional//EN">
以降が出力されることは無いと思うのですが。

ほとんど
header('Location: http://192.168.0.22/~yuuji/kadai/kadai/member.php');
1行だけのスクリプトです。

ここは、
if (isset($_POST)) {
$id = htmlspecialchars($_POST['id'], ENT_QUOTES);
}
とかするべきと思います。
Parent: 3670  reply: 3681 返信 編集 削除

[3681] ご指摘ありがとうございます

user: PHP勉強野郎! | created: 2007-03-23 18:44
現在、この症状は
$id = strip_tags($_POST['id']);
$pass = strip_tags($_POST['passwd']);
$sec_id = strip_tags($_POST['sec_id']);
$sec_pass = strip_tags($_POST['sec_passwd']);

$result = pg_query($con, "SELECT * FROM test WHERE id = '$id' AND pass = '$pass'");
// フォームから入力された値を条件にデータベースから『id』と『pass』の内容を取得・変数$resultに格納する

if($result && pg_num_rows($result) > 0){
$db_id = pg_fetch_result($result, 0, "id");
$db_pass = pg_fetch_result($result, 0, "pass");

if(strcmp($db_id, $db_pass) == 0){
session_start();
$_SESSION['id'] = $id;
$url = "http://*****/member.php"; // 指定URL
header('Location: '. $url); // HTTPヘッダを送信する
// メッセージを出力し、カレントのスクリプトを終了する
} elseif(strcmp($db_id, $db_pass) == 1) {
session_unset();
echo "ユーザーが存在しないか、パスワードが間違っています。";
}
}
とする事で解消されました。
至らない点、出来ていない点をわざわざご指摘頂き本当に
感謝しております。 ありがとうございました。
Parent: 3679  返信 編集 削除
スレッド表示 | フラット表示〕 全トピック 920 件中 128 番目 次≫ ≪前
ページの一番上へ
Googleグックマークに登録 Yahooグックマークに登録 livedoorクリップに登録 @niftyクリップに登録 はてなブックマークに登録 deliciousに登録 Buzzurlに登録 FC2ブックマークに登録
最近更新された掲示板トピックス
管理人Blog
Yahoo Search

最近更新したNote
PHPマニュアル
今日のブックマーク
PHPマニュアル関数検索
関数名を入力し検索ボタンをクリック↑