• ベストアンサー

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)■■■■ }

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

  • ベストアンサー
  • bm_hiro
  • ベストアンサー率51% (200/388)
回答No.2

全く 検証してませんし、ざっと読んだだけで ???となった箇所があります。 > //■■■■メールに書いてあるクリックされた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 . どんなパラメータを投げていますか?

reimy1
質問者

お礼

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

reimy1
質問者

補足

両方 explode でしたね。試して問題ないようです。 投げているパラメータは http://www.XXX.com/test.php?password=XXXX&username=hoge のようなものです。 $urlpassは配列でした。だから$urlpass[1]となります。 likeは不必要かもしれません。検証してみます。

その他の回答 (3)

  • bm_hiro
  • ベストアンサー率51% (200/388)
回答No.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'];

reimy1
質問者

お礼

likeは不必要でしたね。完全一致で問題ないので おっしゃるとおりusername='hoge'ですね。 またスーパーグローバル変数でも使えましたので これもおっしゃるとおり $urlpass = $_GET['password']; $username = $_GET['username']; で修正します。 ありがとうございました。

noname#243182
noname#243182
回答No.3

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

参考URL:
http://php.net/manual/ja/reserved.variables.get.php
reimy1
質問者

お礼

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

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

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

reimy1
質問者

お礼

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

関連するQ&A