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

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

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

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

PHP

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

CodeIgniter

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

Q&A

解決済

1回答

1671閲覧

バグの回避について

destrudo

総合スコア143

MySQL

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

PHP

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

CodeIgniter

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

0グッド

0クリップ

投稿2017/03/24 14:01

<?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で判定するにはどういったものを使えば良いかヒントお願いします。一応今のコードでも動くのですが、やはりこの書き方はよくないでしょうか。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

archiver

2017/03/24 15:13

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

2017/03/24 16:00

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

2017/03/24 16:20

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

2017/03/25 15:27

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

回答1

0

ベストアンサー

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

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

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

投稿2017/03/24 15:13

編集2017/03/24 15:43
yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

destrudo

2017/03/24 16:02

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

2017/03/24 16:41

重複を許す以上、そのバグは解消できません。 他になにかユーザーを一意にする情報を追加しないといけません。 また、それはバグではなく仕様設計もれです。
destrudo

2017/03/25 03:20

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

2017/03/25 03:34

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

2017/03/25 05:07

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

2017/03/25 05:14

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

2017/03/25 06:01

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

退会済みユーザー

2017/03/25 06:38

横から失礼。 ログインシステムの定石をまず押さえる必要があるかと思います。 http://qiita.com/ShibuyaKosuke/items/f114ffccf441edb2b745 こちらを参考に、ログインシステムの挙動を学習されては? 丁寧に解説してくれているので、CodeIgniter への実装もそれほど難しくありません。 逆に、Ion Auth なりのライブラリを導入して、動作を確認するのでも良いかと思います。 http://blog.a-way-out.net/blog/2015/06/08/codeigniter-ion-auth/ *日本語化する時にちょっと課題があった気がします。ちゃんと覚えていませんが。学習であれば、英語ページで良いので、手順通り進めればよいかと。 ログインシステムは、それなりに経験がなければ、すぐにセキュリティホールが出来てしまう機能なので、独自設計ですすめるよりも、基礎をちゃんと押さえたほうがが良いです。
destrudo

2017/03/25 15:26

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

2017/03/25 16: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です。どういうことなんでしょうか
yona

2017/03/25 16:56

私が張ったリンクにsimple_queryを使うとは書いていないですよね? リファレンスをしっかり読んでから質問してください。 また、simple_queryはSQLとして正しいかどうかを判断するメソッドであり、結果が返ってくることはありません。このメソッドがfalseを返すならそのSQLは正しくありません。 あと、私はidとnameを一度に取得する方法を回答としているので、それ以外の方法で解決したいなら私から言えることはないです。
destrudo

2017/03/25 16:56

失礼、fromは入ってます。
yona

2017/03/25 17:06

fromが入っていようがsimple_queryはfalseを返しているんですよね?その時点でそのSQLは間違っています。 また、リファレンスでresult_arrayについて読んでからコメントしてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問