0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PHPで性格診断アプリを作ってみた

Last updated at Posted at 2020-07-20

性格診断アプリ

前書き

こんにちは。業務としてWebAppエンジニアリングをかじっている者です。今回はXAMPPで性格診断アプリを作ってみました。今まで自分一人でログイン機能付きのアプリを作ったことがなかったのでいい勉強になりました。XAMPPのインストール手順に関しては別記事をご参照ください。ソースコードはこちらです。

構成

XAMPPをインストールするとC:\xampp\htdocsがドキュメントルートになります。例えばこのhtdocs直下にindex.htmlindex.phpなどのindexという名前のファイルを置いた状態で、ブラウザにhttp://localhostと入力するとローカル環境でAppを起動することができます。(事前にXAMPP Control Panel内のApacheをStartさせておいてください)

htdocs下の構成は以下のようになります。

 C:\xampp\htdocs> ls


    ディレクトリ: C:\xampp\htdocs


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2020/07/13     16:41                css
d-----       2020/06/22     10:47                dashboard
d-----       2020/07/13     12:45                img
d-----       2020/06/22     10:47                webalizer
d-----       2020/06/22     10:47                xampp
-a----       2020/07/14     16:19            152 config.php
-a----       2015/07/17      0:32          30894 favicon.ico
-a----       2020/07/15     22:28           5965 home.html
-a----       2020/07/14     16:14           3241 index.php
-a----       2020/07/15     22:29           1524 login.php
-a----       2020/07/14     19:35            909 logout.php
-a----       2020/07/15     22:29           1971 result-list.php
-a----       2020/07/15     22:30          11434 result.php
-a----       2020/07/15     22:03           2174 signUp.php
C:\xampp\htdocs\css> ls


    ディレクトリ: C:\xampp\htdocs\css


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2020/07/15     13:44           1394 style.css

データベースのテーブル構成については以下のようになります。

dbname=pd_login
テーブル: userdata
email  	varchar(255)	utf8mb4_unicode_ci unique key
password	varchar(255)	utf8mb4_unicode_ci

テーブル: diagnosis-result
email	varchar(255)	utf8mb4_unicode_ci
execution_time	datetime
friendly	int(11)
extrovert	int(11)
emotional	int(11)
positive	int(11)
leader	    int(11)

ログイン

htdocs直下にindex.htmlindex.phpなどのindexという名前のファイルを置いた状態で、ブラウザにhttp://localhostと入力するとindex.phpが表示されます。これがログイン機能の大元になるファイルです。新規登録機能と通常ログイン機能を持たせています。新規登録処理について、メールアドレスとパスワードにはフィルターをかけている。パスワードに関しては正規表現で適切でないものをはじいています。メールアドレスに関してはfilter_varを利用して、RFC822で判定しています。RFC822は判定がガバガバ説があるので、ビジネスで使うときは注意です。パスワードはセキュアにデータベースに保存するためpassword_hash()関数を使ってhash化しています。

if (!$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) {
  echo '入力された値が不正です。';
  return false;
}
if (preg_match('/\A(?=.*?[a-z])(?=.*?\d)[a-z\d]{8,100}+\z/i', $_POST['password'])) {
  $password = password_hash($_POST['password'], PASSWORD_DEFAULT);
} else {
  echo 'パスワードは半角英数字をそれぞれ1文字以上含んだ8文字以上で設定してください。';
  return false;
}

通常ログイン機能では以下のようにパスワードを処理します。登録時にhash化したパスワードをpassword_verify()で照合しています。

# login.php
if (password_verify($_POST['password'], $row['password'])) {
  session_regenerate_id(true); //session_idを新しく生成し、置き換える
  $_SESSION['EMAIL'] = $row['email'];
  echo 'ログインしました';
  session_write_close();
  header( "Location: ./home.php" ) ;
  exit();

} else {
  echo 'メールアドレス又はパスワードが間違っています。';
  return false;
}

性格診断

index.php内のinputタグからemailpasswordをpostするとそれをlogin.phpがデータを受け取り、本人確認が済んだらhome.htmlに遷移します。以下がhome.htmlの質問文の箇所です。valueには質問ごとの性格要素の値が入っています。

<form method="post" action="result.php">
    <h2>第一問</h2>
    <p>あなたは外で遊ぶより、家で過ごすほうが好きですか?</p>
    <input type="radio" name="q1" value="1"> かなりそう思う<br>
    <input type="radio" name="q1" value="2"> そう思う<br>
    <input type="radio" name="q1" value="3"> どちらとも言える<br>
    <input type="radio" name="q1" value="4"> あまりそう思わない<br>
    <input type="radio" name="q1" value="5" required> そう思わない<br>

診断結果

home.htmlで入力した値はresult.phpにpostされます。以下はvalueごとの性格要素の値を集計して、4分岐でユーザの性格を判定している箇所です。この例だと質問2と質問6はユーザの興味の対象に関する要素を決定する項目です。この2つの質問のvalueを合算してその合計でユーザの性格を4つに分類しています。

# result.php
if($q2+$q6>8){
              $hito_mono = "非常にモノよりヒト";
              $hito_mono_comment = "あなたは特にこの傾向が強く、ヒトと関わっている時間を楽しみに感じています。
              仕事を選ぶ際にもなるべくヒトと関わる仕事を選ぶとよいでしょう。";
            }elseif($q2+$q6>5){
              $hito_mono = "どちらかといえば、モノよりヒト";
              $hito_mono_comment = "あなたはヒトと関わる時間に楽しみを感じる一方で、モノにも興味をもてます。
              何か自分の興味のあるモノやコトに打ち込みながら、それをヒトとシェアできるバランスの良さをもっています。";
            }elseif($q2+$q6>3){
              $hito_mono = "どちらかといえば、ヒトよりモノ";
              $hito_mono_comment = "あなたはモノやコトに打ち込んでいる瞬間に楽しみを感じる一方で、他人にも興味をもてます。
              何か自分の興味のあるモノやコトに打ち込みながら、それをヒトとシェアできるバランスの良さをもっています。";
            }else{
              $hito_mono = "非常にヒトよりモノ";
              $hito_mono_comment = "あなたは特にこの傾向が強く、モノやコトに打ち込んでいる瞬間を楽しみに感じています。
              仕事を選ぶ際にもなるべく一人で集中できる仕事を選ぶとよいでしょう。";
            }

判定結果の履歴

home.htmlに以下のボタンを設置しています。

<button class="fixed_btn" onclick="location.href='./result-list.php'">過去の診断結果</button>

実はresult.php内でデータベースにそれぞれの結果を保存しています。home.htmlresult-list.phpに遷移した後、このデータベースに接続します。result-list.phpでは以下のような処理を行っており、ログインしているユーザのemailカラムを参考に、データベース内の全データを取得して表として出力しています。

# result-list.php
function createHtmlTable($result) {

    $html = "<table border='3' cellspacing='4' cellpadding='4'>";

    $ffields = $result->fetch_fields();
    $html .= "<tr>";
    foreach ($ffields as $val) {
        $html .= "<th>" . $val->name . "</th>";
    }
    $html .= "</tr>";

    foreach ($result as $row) {
        $html .= "<tr>";
        foreach ($ffields as $val) {
            $value = $row[$val->name];
            $html .= "<td>${value}</td>";
        }
        $html .= "</tr>";
    }
    $html .= "</table>";

    return $html;
}

Session

ちなみに、ページ遷移してもログイン時のemailを利用できるのはSessionを利用しているからです。login.php内では、以下のような処理をしています。

# login.php
$_SESSION['EMAIL'] = $row['email'];

遷移した後のページでこの$_SESSION['EMAIL']を使うときは、以下のような記述をする必要があります。


  <?php
      session_start();

ハマったこと

データベースの接続

文字列の変数はちゃんと'$hoge'などシングルクオーテーションマーク(あるいはダブルクォーテーションマーク)で囲む必要があります。

# result.php
$pdo = new PDO('mysql:host=localhost;dbname=pd_login;charset=utf8mb4','root','');
            $sql = "INSERT INTO `diagnosis-result`(`email`, `execution_time`, `friendly`, `extrovert`, `emotional`, `positive`, `leader`) VALUES ('$user_email','$current_time',$q2+$q6,$q1+$q7,$q3+$q8,$q5+$q9,$q4+$q10)";
            $qry = $pdo->prepare($sql);
            $qry->execute();
            $pdo = null;

データベースのデータ型

パスワードをhash化していますが、長さには余裕をもたせる必要があります。私はvarchar(16)とやってしばらくハマっていました。varchar(255)にしたら通りました。

参考

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?