こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

PHPでの不思議なふるまいが理解できません。MySQLのデータ照合

PHPでユーザーにURLでパラメーター付メールを送り、そのURLをクリックするとMySQLに保存されているユーザー名「hoge」というレコード内のsignという項目の値が0なら1にするというプログラムを書いています。

phpadminでsignが0なのを確認しているのに、URLをクリックしてプログラムを走らせると、//■■■■(3)■■■■の場所で終わってしまいます。(つまり0だと認識されていない?)その場合、echo $pass;の表示はなぜか1です。
echo $pass;は、//■■■■(2)■■■■のsignを1にする前の処理なのになぜ前もって1となるかが分からない点です。

そこでコメントされている■■■■(1)■■■■のexit;を、コメントアウトさせてからプログラムを走らせるとecho $pass;の表示は0です。

この現象が分かる方は教えて欲しいです。
宜しくお願いします。

//(これより以前省略)
$db = mysql_connect($db_host,$db_user,$db_passwd);
$sql = "select * from $db_table where username like 'hoge'";
$result = mysql_query($sql) or die("SQLに失敗しました".mysql_error());


//■■■■MySQLに保存されているデータを抜き出し
$row = mysql_fetch_array($result);
$sign = $row{'sign'};
$pass = $row{'password'};

echo $pass;

//■■■■メールに書いてあるクリックされたURLの分解
$a = explode('&', $_SERVER['QUERY_STRING']);
$urlpass = split('=', $a[1]);


//exit;//■■■■(1)■■■■

if ( $sign == 0 ){

if ( $urlpass == $pass ){sign
$sql = "update $db_table set sign = 1 where username like 'hoge'";■■■■(2)■■■■
$result = mysql_query($sql) or die("SQLに失敗しました".mysql_error());
if ($result){
echo"認証できました。";
}
}else{
echo"認証できません。";
}
}else{//$signが0以外なら
echo"認証済みです";//■■■■(3)■■■■
}

投稿日時 - 2010-02-02 20:08:38

QNo.5644172

困ってます

質問者が選んだベストアンサー

全く 検証してませんし、ざっと読んだだけで ???となった箇所があります。

> //■■■■メールに書いてあるクリックされたURLの分解
> $a = explode('&', $_SERVER['QUERY_STRING']);
> $urlpass = split('=', $a[1]);
・これだと split が explode と同じ役割しかしていないので、両方 explode で いいのでは?
・URLに渡しているパラメータが不明なので、なんともいえませんが、見た感じ「a=1&b=2」みたいなのかと思ったのですが、
これだと$_GETと同じでは?
・上のようなパラメータだとして、$urlpass に入るのは 配列で array(0 => b , 1 => 2) みたいになるのでは?

> if ( $urlpass == $pass ){sign
末尾の「sign」は 削り忘れと解釈しました。
・配列と文字列の比較???内部的には 「Array == $pass」になってるような気が。

> $sql = "update $db_table set sign = 1 where username like 'hoge'";■■■■(2)■■■■
・like の 意味ありますか?イコール と 同じように見えるのですが。。


Q . どんなパラメータを投げていますか?

投稿日時 - 2010-02-02 21:17:17

補足

両方 explode でしたね。試して問題ないようです。

投げているパラメータは
http://www.XXX.com/test.php?password=XXXX&username=hoge
のようなものです。
$urlpassは配列でした。だから$urlpass[1]となります。

likeは不必要かもしれません。検証してみます。

投稿日時 - 2010-02-02 21:53:06

お礼

bm_hiroさんはじめ
みなさんの通り修正しましたが
やはり//■■■■(3)■■■■の処理に入ってしまいます。
でも色々勉強になりました。
ありがとうございました。

投稿日時 - 2010-02-03 18:34:06

ANo.2

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(4)

ANo.4

> likeは不必要かもしれません。検証してみます。
like は 俺の認識では 前方一致(like 'hoge%') とか 後方一致(like '%hoge')のような時に使うものだと思ってます。
ユーザー名の場合は、完全一致の必要があるものだと思いますので、
username='hoge'
であるべきかな~。と思います。

> //■■■■メールに書いてあるクリックされたURLの分解
> $a = explode('&', $_SERVER['QUERY_STRING']);
> $urlpass = split('=', $a[1]);
↑ は スーパーグローバル変数に縛りがなければ↓ で OKです。
$urlpass = $_GET['password'];
$username = $_GET['username'];

投稿日時 - 2010-02-02 23:03:54

お礼

likeは不必要でしたね。完全一致で問題ないので
おっしゃるとおりusername='hoge'ですね。

またスーパーグローバル変数でも使えましたので
これもおっしゃるとおり
$urlpass = $_GET['password'];
$username = $_GET['username'];
で修正します。
ありがとうございました。

投稿日時 - 2010-02-02 23:07:39

PHPではクエリ文字列を分解せずとも、スーパーグローバル「$_GET」を利用することでより簡単に必要とする値を取得できます。

参考URL:http://php.net/manual/ja/reserved.variables.get.php

投稿日時 - 2010-02-02 21:47:58

お礼

本当ですね。
$_SERVER['QUERY_STRING']より記述が楽です。
勉強になりました。採用します。

投稿日時 - 2010-02-02 22:52:42

ANo.1

>$sign = $row{'sign'};
>$pass = $row{'password'};

これって$rowは配列なので
$sign = $row['sign'];
$pass = $row['password'];
じゃないですか?

投稿日時 - 2010-02-02 21:04:34

お礼

[]で囲むのが正解ですね。
間違っていました。
ありがとうございました。

投稿日時 - 2010-02-02 22:11:10

あなたにオススメの質問