プロが教える店舗&オフィスのセキュリティ対策術

お世話になります。

PHPからDBにレコード登録についてお聞きしたいことがあり、ご質問させていただきました。

初心者のためご教授いただければと思います。

サーバーはさくらインターネット
PHPは5.2.12
データベースはMySQL 5.1

<?php




$link = mysql_connect($DB_HOST,$DB_USER,$DB_PASS;
mysql_select_db($DB_NAME,$link);
mysql_set_charset('sjis',$link);

$id = addslashes($_POST['id']);
$password = addslashes($_POST['password']);
$first_name = addslashes($_POST['first_name']);
$last_name = addslashes($_POST['last_name']);
$year = addslashes($_POST['year']);
$month = addslashes($_POST['month']);
$day = addslashes($_POST['day']);

$query_reg = sprintf("INSERT INTO member (id,password,first_name,last_name,first_kana,last_kana,year,month,day) VALUES('$id','$password','$first_name','$last_name','$first_kana','$last_kana','$year','$month','$day')");
$result_reg = mysql_query($query_reg, $link);



?>
<html>
<body>
<form action="completion.php" method="POST">
<input type="text" name="id"/><br>
<input type="text" name="password" />
<input type="text" name="first_name"/>
<input type="text" name="last_name"/>
<input type="text" name="first_kana" />
<input type="text" name="last_kana" />
<?php
//年の入力
print '<select name="year">' . "\n";
$start = date('Y') -29;
$end = date('Y') -16;
for ($i = $start; $i <= $end; $i++) {
$selected = "";
$selected = ($_SESSION["year"] == sprintf("%04d",$i)) ? "selected":"";
print '<option value="' . sprintf("%04d",$i) . '" '.$selected.'>' . sprintf("%04d",$i) . '</option>' . "\n";
}
print '</select> 年' . "\n";
//月の入力
print '<select name="month">' . "\n";
for ($i = 01; $i <= 12; $i++) {
$selected = "";
$selected = ($_SESSION["month"] == sprintf("%02d",$i)) ? "selected":"";
print '<option value="' . sprintf("%02d",$i) . '" '.$selected.'>' . sprintf("%02d",$i) . '</option>' . "\n";
}
print '</select> 月' . "\n";

//日の入力
print '<select name="day">' . "\n";
for ($i = 01; $i <= 31; $i++) {
$selected = "";
$selected = ($_SESSION["day"] == sprintf("%02d",$i)) ? "selected":"";
print '<option value="' . sprintf("%02d",$i) . '" '.$selected.'>' . sprintf("%02d",$i) . '</option>' . "\n";
}
print '</select> 日' . "\n";
?>
<input type="submit" value="登録">
</form>

と記述しています。

ですが、調べたコードを自分の環境に変更しながら記述したのですが、データベースでは真っ白の状態で登録されてしまいます。
(真っ白の状態というよりフォームで入力した内容が表示されない。)

phpファイルはShift-JISで記述しています。

どなたかお分かりの方がいらっしゃいましたら、ご教授お願いいたします。

A 回答 (4件)

$query_reg = ・・・のあとに


print $query_reg;
として意図したsqlが発行されているか確認してください。

また、
$result_reg = mysql_query($query_reg, $link) or die(mysql_error());
でデバグできます。

それとテーブル名、フィールド名はすべて``で囲んでください

`member` (`id`,`password`,`first_name`,・・・・

基本的にshift-jisを使っている限りインジェクションは
なくなりませんのでそれなりの覚悟が必要です。

この回答への補足

yambejpさん
ご回答有難う御座います。

>それとテーブル名、フィールド名はすべて``で囲んでください
>`member` (`id`,`password`,`first_name`,・・・・

このように''で囲ったところデータ登録ができなくなりました。
データ登録といっても何も登録がされず、空白のレコードだけが増えるだけですが・・・

>$query_reg = ・・・のあとに
>print $query_reg;
>として意図したsqlが発行されているか確認してください。

if (!$result_reg) {
print 'メンバーが登録されませんでした。';
}
のように記述しました。

間違っていないでしょうか?

補足日時:2010/03/21 21:11
    • good
    • 0

>空白の部分(入力するのを飛ばした部分)があると登録ができずエラー表示されてしまいます。



すみません、こまかく検証していないので状況がよくわかりませんが、
INSERT時のエラーであれば 「INSERT IGNORE INTO」でエラーを
回避する手はあります。
この場合すでにデータがあれば挿入しないという意味になります。

>数字(0が省かれる)が登録されてしまいます。

考え方が二つあります。
一つは文字列系のデータで処理する。varcharとかcharとか

もう一つはintで処理して長さを2としてunsigned zerofillを
指定しておくと、0で左側を埋めてくれます。

この回答への補足

yambejp 様
ご回答有難う御座います。

>もう一つはintで処理して長さを2としてunsigned zerofillを
>指定しておくと、0で左側を埋めてくれます。
こちらで処理しました。

varcharでやっていたのですが、できなかったので・・・

>INSERT時のエラーであれば 「INSERT IGNORE INTO」でエラーを
>回避する手はあります。
>この場合すでにデータがあれば挿入しないという意味になります。

こちらは少し調べてみます。

調べてもわからない場合はまたご質問するかも知れませんが、そのときは宜しくお願いいたします。

本当有難う御座いました。

補足日時:2010/03/23 23:58
    • good
    • 0

>このように''で囲ったところ



シングルクォーテーションではなくバッククォーテーションですが
間違いないですか?

この回答への補足

yambejp 様
ご回答有難うございます。

勘違いしておりました。
``に変更しました。

それと2つほどご質問なのですが、
1つ目はフォームでデータを入力し、データベースに登録する流れなのですが、空白の部分(入力するのを飛ばした部分)があると登録ができずエラー表示されてしまいます。
空白でもデータベースに登録されるにはどうしたらよろしいでしょうか?

2つ目は上記のフォームにて誕生日のセレクトボックスを選択する際に一桁の数字(フォームの表示では01月~09月と01日~09日まで)を選択するとデータベースに一桁の数字(0が省かれる)が登録されてしまいます。
こちらも0がついている状態(01,02,・・・)で登録されるにはどうしたらよろしいでしょうか?

補足日時:2010/03/23 17:18
    • good
    • 0

year,month,dayに関しては、MYSQLの組み込み関数として存在していますので、その当たりが絡んでいるのではないかという気がします。



一旦、それらyear,month,dayを外した以下のようなクエリーで試してみてください。
$query_reg = "INSERT INTO member (id,password,first_name,last_name,first_kana,last_kana) VALUES('$id','$password','$first_name','$last_name','$first_kana','$last_kana')";
※当然、外したyear,month,dayには、データは入りません。それ以外の部分にデータが入るかというテストです。

もうひとつ考えられるのは、上記のyear,month,dayが数値型(整数型/INT/Integerなどの表記もあり得る)で作成されてはいないかという点です。
その場合、VALUES以下で、'$year','$month','$day'のように、''で囲む必要はありません。
※こちらの原因だとしても、一旦year,month,dayを外したクエリーでは動くでしょう。

もし上記で動いた場合、
各フィールド名(項目名)を、b_year,b_month,b_dayのようにDBを変更して(項目が誕生日かなと思ったので、birthdayの意味でb_と書きましたが)、数値型ならば''を外せばOKだと思います。

上記で動かなければ別の原因ですが、たぶん上記の二つが原因と言うことで間違いないでしょう。

ちなみに、addslashesの部分ですが、mysql_real_escape_stringを使用する方がお奨めです。

この回答への補足

BellBellさん
ご回答有難う御座います。

$query_reg = "INSERT INTO member (id,password,first_name,last_name,first_kana,last_kana) VALUES('$id','$password','$first_name','$last_name','$first_kana','$last_kana')";

に変更し、もう一度フォームからデータを挿入してみたのですが、変わらず同じ現象になってしまいます。

ちなみにyear,month,dayは誕生日なのですが、そちらはフォームからも省いております。

補足日時:2010/03/21 21:05
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!