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

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

ただいまの
回答率

90.33%

  • PHP

    21354questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • MySQL

    6183questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • CodeIgniter

    281questions

    CodeIgniterは、PHP向けオープンソースのWebアプリケーションフレームワークです。CodeIgniterは覚える構文が少なく、自由度も高いため、PHPを理解していれば構築が簡単です。

バグの回避について

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 469

destrudo

score 111

<?php
class Controllers_login extends CI_Controller{
    public function __construct(){
        parent::__construct();
        $this->load->database();
        $this->load->library('session');
        $this->load->helper('url');
        $this->load->library('form_validation');

    }

    public function index(){
        $this->load->view('views_mainpage');    
    }

    public function first_login(){


        $this->load->view('views_login');
    }
    public function main(){
        $this->form_validation->set_rules('email','mailaddress','required');
        $this->form_validation->set_rules('password','mypassword','required');
        if($this->form_validation->run()==FALSE){
                        $this->load->view('views_error');
        }    
        else{
            $email=$this->input->post('email');
            $password=$this->input->post('password');

            $this->load->model('models_login');
            $number_row=$this->models_login->exist_func($email,$password);

            //この辺がバグの原因になりうる
            if($number_row>0){
            //get id by this email and password
                $user_id=$this->models_login->get_id($email,$password);//!!!



                $this->session->set_userdata(array('id'=>$user_id['id']));

                $this->session->userdata('id');
                $session_id =array('id'=>$user_id['id']);

                //get name by this session id
                $name_data['name']=$this->models_login->get_name($session_id);

                //send name for view 
                $this->load->view('views_mainpage',$name_data);
            }
            else{
                //$this->load->view('views_login');
                $this->load->view('views_error');
            }

        }
    }

    public function logout(){
        $this->session->sess_destroy();

        redirect("controllers_login");

    }    
}
?>
<?php
class models_login extends CI_Model{
    public function __construct(){
        parent::__construct();
        $this->load->database();
        $this->load->library('session');
        $this->load->helper('url');
        $this->load->library('form_validation');
    }

    public function exist_func($email,$password){
        $sql="SELECT*FROM login WHERE email=? AND password=?";
        $query=$this->db->query($sql,array($email,$password));
    //この辺がバグの原因になりうる    
     $number_result=$query->num_rows();    

        return $number_result;
    }




    public function get_id($email,$password){
        $sql="SELECT id FROM login WHERE email=? AND password=?";
        $query=$this->db->query($sql,array($email,$password));
        $row=$query->row_array();
        return $row;
    }




    public function get_name($session_id){
        $sql="SELECT name FROM login WHERE id=?";

        $query=$this->db->query($sql,array($session_id));
        $row=$query->row_array();

        return $row;
    }    

}
?>        


ログイン認証についての質問です。
フォームに入力したメールアドレスとパスワードが一致した行数を返して、
0より大きいかを判断するのがif($number_row>0)なのですが、このようなやり方だと、同じメールアドレスとパスワードが2件あった場合にバグの原因になるようです。データベースの方でユニークを設定する以外で考えています。ログインできたかログインできなかったかをtrueかfaulseで判定するにはどういったものを使えば良いかヒントお願いします。一応今のコードでも動くのですが、やはりこの書き方はよくないでしょうか。

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • archiver

    2017/03/25 00:13

    データベースでユニークに設定する以外の方法を模索しているのは何故でしょうか?DBの登録上、重複しますが。

    キャンセル

  • destrudo

    2017/03/25 01:00

    コード上で修正したいからです。

    キャンセル

  • archiver

    2017/03/25 01:20

    DB側の構成・設定が変更できないので、コードでそれをカバーするということですか?(コメントを踏まえても、DBの設計バグとしか思えませんが)ちなみに、このシステムは運用段階なのですか?(テスト段階ならば、DBの設計を見直した方が早い気がします)

    キャンセル

  • destrudo

    2017/03/26 00:27

    勉強段階です。色々な方法知っていた方がいいかと思って。

    キャンセル

回答 1

checkベストアンサー

+5

どのようかバグを想定しているかを書いてください。

また、クエリを3回に分ける必要はないですね。
idとnameを一度に取得するように修正すればユーザーの存在確認とid・nameの情報は一度で取得できるのでバグは起きないです。

重複を許す以上、複数個のidとnameが帰ってきた時になにを基準に選ぶかを決めないといけません。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/03/25 01:02

    同じメールアドレス、パスワードの人が存在したために、例えばマイページに飛んだ時に違う人のページが表示されてしまうというバグです。

    キャンセル

  • 2017/03/25 01:41

    重複を許す以上、そのバグは解消できません。

    他になにかユーザーを一意にする情報を追加しないといけません。

    また、それはバグではなく仕様設計もれです。

    キャンセル

  • 2017/03/25 12:20

    今更気づいたのですが、if($number_row=1)にすれば解決だったかもしれません。

    キャンセル

  • 2017/03/25 12:34

    横から失礼します。
    if($number_row==1) ですよね?
    これだと、複数件登録されているユーザーは除外されます。それは意図していることではないですか?

    問題の本質は理解できてますか?

    キャンセル

  • 2017/03/25 14:07

    if($number_row==1)ですね。
    元々データベースに複数件同じメールアドレス、パスワードが存在する前提だとこの条件は問題ですね。
    データベースに今後登録する際にメールアドレスをユニークにしようと思います。その上で
    if($number_row==1) にすれば良いでしょうか。重複許す設定がまずそもそもダメということでしょうか。

    キャンセル

  • 2017/03/25 14:14

    でもif($number_row==1)にすると
    モデルの$number_result=$query->num_rows();
    このnum_rows();っていうのもなんというか違和感ありますね。
    結果は1か0しかないのに使い方が変というか・・・
    同じことではあるんですけども。
    もっとスマートな方法あればってところですね。
    tureかfalseで判定するような。

    キャンセル

  • 2017/03/25 15:01

    そもそも行数を取得する必要はないですよ。
    1-回答に書いたようにメールアドレスとパスワードで検索する。
    2-idとnameが取得できた。→ユーザーがいる。
    3-idとnameが取得できなかった。→ユーザーがいないのでエラーにする。

    キャンセル

  • 2017/03/25 15:38

    横から失礼。

    ログインシステムの定石をまず押さえる必要があるかと思います。
    http://qiita.com/ShibuyaKosuke/items/f114ffccf441edb2b745
    こちらを参考に、ログインシステムの挙動を学習されては?
    丁寧に解説してくれているので、CodeIgniter への実装もそれほど難しくありません。

    逆に、Ion Auth なりのライブラリを導入して、動作を確認するのでも良いかと思います。
    http://blog.a-way-out.net/blog/2015/06/08/codeigniter-ion-auth/
    *日本語化する時にちょっと課題があった気がします。ちゃんと覚えていませんが。学習であれば、英語ページで良いので、手順通り進めればよいかと。

    ログインシステムは、それなりに経験がなければ、すぐにセキュリティホールが出来てしまう機能なので、独自設計ですすめるよりも、基礎をちゃんと押さえたほうがが良いです。

    キャンセル

  • 2017/03/26 00:26

    ありがとうございます。それならrow使う必要なくtrue,falseできますね。sql文でidとnameを取得するには、select id,name from login where email=? and password=?になりますが、nameだけを結果に返すことってできるのでしょうか。それがよく分からなくてクエリを一個ずつ分けていたんですよね。

    キャンセル

  • 2017/03/26 00:39 編集

    リファレンスを読みましょう。
    result_array
    https://www.codeigniter.com/userguide3/database/results.html

    キャンセル

  • 2017/03/26 01:31

    public function exist_func($email,$password){
    $sql="SELECT id,name login WHERE email=? AND password=?";
    $judge=$this->db->simple_query($sql,array($email,$password));
    var_dump($judge);
    return $judge;
    }
    すみません。
    if($judge==true)
    このようにしてログイン判定をしようと思ったのですが、正しいメールパスワードを入力したにも関わらずsimple_queryにfalseがに返ってきます。間違ったデータを入れた場合も同様falseです。どういうことなんでしょうか

    キャンセル

  • 2017/03/26 01:56

    私が張ったリンクにsimple_queryを使うとは書いていないですよね?
    リファレンスをしっかり読んでから質問してください。

    また、simple_queryはSQLとして正しいかどうかを判断するメソッドであり、結果が返ってくることはありません。このメソッドがfalseを返すならそのSQLは正しくありません。

    あと、私はidとnameを一度に取得する方法を回答としているので、それ以外の方法で解決したいなら私から言えることはないです。

    キャンセル

  • 2017/03/26 01:56

    失礼、fromは入ってます。

    キャンセル

  • 2017/03/26 02:06

    fromが入っていようがsimple_queryはfalseを返しているんですよね?その時点でそのSQLは間違っています。

    また、リファレンスでresult_arrayについて読んでからコメントしてください。

    キャンセル

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

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

同じタグがついた質問を見る

  • PHP

    21354questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • MySQL

    6183questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • CodeIgniter

    281questions

    CodeIgniterは、PHP向けオープンソースのWebアプリケーションフレームワークです。CodeIgniterは覚える構文が少なく、自由度も高いため、PHPを理解していれば構築が簡単です。