質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.64%

再 条件ごとにリダイレクトをしたい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,734

fgfnabwym

score 72

ユーザーのユーザー名とパスワードが合っていた時、$fstatusの値がusrのユーザーは利用者ページに。$fstatusの値がusrのユーザーは管理者ページに送りたいです。

ですが、$fstatusの中身が認識されません。$_SESSION['fstatus'] をif文に使った時もです。
echoで変数の中身を出力すると、どちらとも、usrまたはadmのどちらかの値が入っています。値が入っているのにif文で認識してもらえないのはどうしてでしょうか。

下の書き方だと、条件を判断せず、正しいユーザー名とパスワードを入力してもエラーとなってしまいます。 

どうすれば$fstatusの値を認識し、if文を使えるようになるでしょうか。

<?php
session_start();
$id = @$_POST['ID'];  // ユーザーID
$pwd = @$_POST['PWD'];  //パスワード

// ログインボタンが押された場合
if (isset($_POST["login"])) {

    // IDとパスワードを結合する
    $namedata = $id."%".$pwd;

    // ファイルを開く
    $fp = fopen("usrlist.txt", "r");
    while(!feof($fp)) {
        $buffer = fgets($fp);  // 1行ずつ読み込み
        if (strstr($buffer, $namedata)) {    // 結合した文字列があった時
            $line=$buffer;
            $word = explode("%",$line);
            $fid = $word[0]; // ID
            $fpwd = $word[1]; // PWD
            $fname = $word[2]; // 名前
            $fstatus = $word[3]; // 状態  値が admは管理者ページ。usrは利用者ページへ

            $_SESSION['fname'] = $fname;
            $_SESSION['fstatus'] = $fstatus;


            // 認証成功
            // ユーザー名、パスワードが合っていた
            if ($_POST['ID'] == $fid && $_POST['PWD'] == $fpwd) {
                // セッションIDを新規に発行する
                session_regenerate_id(TRUE);
                $_SESSION["USERID"] = $_POST['ID'];
                if ($fstatus == 'adm'){
                    header("Location: admtop.php");  // 管理者トップ画面へ移動する
                   exit;
                } else {
                header("Location:usrtop.php");  // 利用者トップ画面へ移動する
                exit;
                }
            }
        }
    }
 
?>

 エラーが出るというのは自分が書いたechoの「ログインできませんでした。」という文字です。勘違いをさせてしまいすみません。

ユーザー名、パスワードがあっていて、ログインするときに、$fstatusがadmでもすべてfalseになり、usrtop.phpにとばされます。
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • yuba

    2015/09/02 23:21

    「エラー」とは一体どんなエラーメッセージが吐き出される状態でしょう?

    キャンセル

  • yuba

    2015/09/02 23:38

    「ログインできませんでした。」とはどこにも書いていませんが、なぜ出てくるのでしょう?
    また、「ログインできませんでした。」と表示されるのですか、それともusrtop.phpに飛ばされるのですか、それともusrtop.phpに飛ばされた結果として「ログインできませんでした。」と表示されるのですか?

    キャンセル

  • fgfnabwym

    2015/10/21 00:41

    yubaさん、情報の追加・修正を依頼していただいたのに、返事をせずに、すみませんでした。
    解決することが出来ました。ありがとうございました。

    キャンセル

回答 3

checkベストアンサー

+1

notableさんの指摘の通りですが、改行を削除していないので、$fstatus は、"adm\n" または "usr\n" になっているはずです。改行を削除するか、"adm\n"と比べるか。

あと、回答ではないですが、プログラムの悪い点の指摘。
・あなた一人しか使わないシステムなら良いですが、他人も使うシステムの場合、パスワードを平文で保存してはいけません。これは絶対。
・簡単に回避できるエラーや警告の抑止のために@を使ってはいけません。
・fopen後に$fpの値のチェックが必要。fopenに失敗するとfeof($fp)が常にFALSEとなりwhileが無限ループになります。
・while条件は、while(($buffer=fgets($fp))!==FALSE) がいい。feofで調べると最終行を読んでからもう一回ループが回りfgetsしてしまう。

悪い点ではないが、改善した方が良い点。
・後半で、IDとパスワードをチェックしているのと、最初にstrstrでIDとパスワードを結合した文字列が含まれているのかのチェックに重複感あり。最初のstrstrのくだりは不要のはず。ただここで、while条件がfeofのままだと、上記のwhileが余計にもう一回回ってしまう問題で、最後に$bufferにFALSEが入り、それへの考慮が必要。やはりwhile条件ではfeofを使うべきでない。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/10/21 00:44

    otnさん、回答ありがとうございました。
    プログラムの悪い点、改善した方が良い点も教えていただいたので、ベストアンサーにしました。
    一人では何も気が付かないので、助かりましたし、勉強になしました。

    キャンセル

+1

if ($fstatus == 'adm'){
の直前で
echo $fstatus;
exit;
if ($fstatus == 'adm'){
のようにすると adm や usr が表示されるということですよね?
それでもheader("Location: admtop.php");に行かないということであれば
$fstatusの中にいらない空白などが入っていないか確認したほうが良いかもしれません。
echo '|'. $fstatus. '|';
exit;
if ($fstatus == 'adm'){
のような感じで出力してみたらわかると思います。
もし空白が入っていればtrim関数などで除去すると良いと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

おそらく usrlist.txt は次のように書かれているのではないでしょうか?

id1%password1%user1%adm
id2%password2%user2%usr

この場合fgetsで読み込むと、改行コードも含んでしまうため $line には「id1%password1%user1%adm\n」が代入され、$fstatusには「adm\n」が代入されることになります。

"adm" == "adm\n"

は成立しないのでログイン処理ができないのだと思われます。
notable さんが紹介している「trim関数」では改行コードは除去できないので「rtrim関数」を使ってみてください。


また、本質問と直接的には関係ないのですが

// 認証成功
// ユーザー名、パスワードが合っていた
if ($_POST['ID'] == $fid && $_POST['PWD'] == $fpwd) {

ここの if は必要なのでしょうか?

if (strstr($buffer, $namedata)) {    // 結合した文字列があった時

ここの if と被っているように思われます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/09/03 00:28

    strstrだけだと、例えばパスワードがabcのときaだけ入れれば、条件が真になりますので、後半のチェックは必要。strstrの方が不要です。

    キャンセル

  • 2015/09/03 00:31

    なるほど。
    ご指摘ありがとうございました。

    キャンセル

  • 2015/09/03 09:08

    念のためコメントするのですが、
    trim関数は第2引数を指定しなければ先頭や末尾の改行(\nや\n)も含めて削除します。
    マニュアルに記載されていますし、実動作もそうです。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.64%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる