【ポートフォリオ】memopaについて（FWなし、素のPHPで作成）

#はじめに
はじめまして。
ご覧いただきありがとうございます。
現在勉強中のPHP言語のアウトプットを兼ねて、ポートフォリオを作成しました。

この記事では、PHP言語を使用してフルスクラッチで作成した「memopa」について説明していきます。

#ポートフォリオのURL

https://memopa.site


#memopaの使い方

![memopa_use01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319229/adccd324-c5d2-94cd-fcb6-866d3987e4c5.gif)


新規会員登録（orログイン）
↓
ヘッダー部分にある「リストを作成」でメモのリスト名を決める
↓
画面に現れるリスト下部「さらにメモを追加する」より、どんどんメモを追加していく

という流れになります。


#ポートフォリオ概要

メモ投稿サイト。カテゴリにわけてメモを管理できるサイトです。
メモだけでなく、todo管理としても使えます。


#使用技術・使用サーバー

html5
css3
javascript
jQuery ver3.4.1
PHP ver7.2.10
MySQL ver5.7
を使用。

サーバー：Xserver



#主な機能

・ユーザー管理機能（フレームワークを使わず、PHPを使用）
ユーザー登録機能
ユーザーログイン機能
ユーザーログアウト機能
ユーザー退会機能
ユーザー編集機能


・メモ管理機能（フレームワークを使わず、PHPを使用）
メモのリスト（カテゴリ）作成、編集機能
メモのタイトル、コンテンツ作成、編集機能
メモ一覧表示機能
メモのリスト一括削除機能
メモ単体の削除機能


・その他の機能（フレームワークを使わず、PHPを使用）
パスワード再設定機能



#具体的な機能について


##【メモ機能】
###メモのタイトル・内容を入力し、投稿。新規作成か編集かはif文で分岐作成。


<img width="621" alt="スクリーンショット 2019-08-20 1.31.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319229/d3ec1a25-f87a-139b-3b01-ffe27c125718.png">

$edit_flgを用意し
以下の2つの画面に切り替えています。(上記コード参照)
![スクリーンショット 2019-08-20 1.26.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319229/3c1868ed-531a-5a6e-2924-b2f9a8c4b165.png)


![スクリーンショット 2019-08-20 1.26.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319229/bdaa669e-91cd-f972-77f8-b05180cf5c82.png)


また、メモ作成時にはPHP側で以下のバリデーションチェックを行っています。

・未入力チェック
・最大文字数チェック
・カテゴリのセレクトボックスチェック


###メモ一覧機能ではカテゴリを分けて、メモタイトルを表示。


![スクリーンショット 2019-08-24 2.15.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319229/35ce40a5-d6dc-7c31-7b9f-89384fdec8ae.png)




カテゴリには**カテゴリid**を
「さらにメモを追加する」にも**カテゴリid**
メモには**メモid**を
パラメータに含めています。

そのため、メモを選べばそのメモをすぐ編集可能。
カテゴリ脇の鉛筆マークを押せば、カテゴリ名を変更可能。
「さらにメモを追加する」を選べば、そのカテゴリにメモを追加できます。

###メモ内容の暗号化、復号化


DBに登録する際、openssl_encrypt()を使いメモの内容を暗号化しています。
（ポートフォリオなので個人の大事な情報を入力していないと思いますが念の為）
編集画面にてメモ内容を表示する際に、openssl_decrypt()を使い復元をしています。

SQL文作成時に暗号化し、
復号化はメモ画面に呼び出すタイミングで行っています。


<img width="570" alt="スクリーンショット 2019-08-20 9.56.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319229/6fa6e9a3-bd5f-b491-0d2f-bc509016bfe6.png">


##【ユーザー管理機能】
###ユーザー管理機能では、ユーザー登録、ログイン、ログアウト、退会機能を作成。
ユーザー登録、ログイン時のバリデーションチェックは以下のものを行なっています。

・未入力チェック
・emailの形式チェック
・emailの重複チェック
・最大文字数チェック
・パスワードの最小文字数チェック
・パスワードの半角英数字チェック
・パスワードの同値チェック



同じメールアドレスで登録できないよう、DBと照らし合わせてメール重複チェックを行なっています。

パスワードを保存する際は、password_hashによるパスワードハッシュ化を行なっています。
→ログイン時にpassword_verifyを使用し、ハッシュ化されたパスワードと照合しています。



###パスワードリマインダーページを設置し、パスワードの再発行（ランダム作成）可能。

memopaに登録したメールアドレスをフォームに入力
↓
そのメールアドレス宛に認証キーを送信。
↓
その認証キーを画面に入力するとランダムでパスワードが作成され、そのランダムのパスワードが再度メールアドレスに送られる。
↓
一度そのパスワードでログイン後、ユーザー側で任意のパスワードを再設定。


という仕組みを作り、パスワードを忘れたユーザーへ対応可能。



##【その他】
###セッション：session_regenerate_id関数によるなりすまし防止

セッションIDをワンタイム化してしまい、攻撃されにくくする手段としてsession_regenerate_id関数を使用。
ワンタイム化するとアクセスするたびにセッションIDが変更されるので、特定を難しくしました。


###DB接続時：プレースホルダによるSQLインジェクション対策

不正にSQLが書き換えられないように、DBに登録したい情報を入れる場所をSQL中にプレースホルダで確保。
あとからデータを流し込むことで、不正な値を入れてもSQLとして実行されない仕組みにしました。

※SQLインジェクションとは？
　データベースに対する命令文の改ざんを行い意図しない操作を行うこと。
　

###htmlspecialcharsを使い、HTMLエンティティ化

PHPで「echo」を使ってDB上に保管してあるデータを呼び出すとき、htmlspecialchars関数によってユーザーが入力したテキストを無害化しています。
（HTMLには特殊な役割を持っている文字（<や>など）があり、その文字をHTMLでの役割としてではなく、ただの文字（見た目は記号）として表示させるため。）


#作成の流れ

1.構想：　必要な機能を洗い出し
 2.テーブル設計：その機能を実現するために必要なテーブルの整理（第1,2正規化）。
3.準備：　Adobe XDでワイヤーフレームを作成

4.制作：　各ページの作成 　
ユーザー管理グループとメモグループの２つに大まかに分け、ユーザー管理グループのページから作成。
その後メモグループのページを作り、機能の拡張を繰り返す。

5.デバッグ: エラーや処理の流れを追うためにログを吐き出すファイルを作成。
その処理の流れを見て、エラーが発生していたら解決＆解決。

「なぜ表示させたい情報が画面に出力されないのか？」
「なぜ画面が真っ白になるのか？」
といったエラーに仮設を立て原因を探る。そして実験を繰り返す。



#作成の期間

約41日　131hほど
（アプリに記録している学習時間より算出）


<img width="375" alt="IMG_6411.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319229/04fed55d-999d-07e7-fadd-415000d4de81.png">



#memopaの課題

・ユーザーが使いたくなるような動機づけとサービスへの流入経路の検討
・メモを削除後、削除メモをアーカイブ化→誤削除への対処
・検索機能の作成
・モバイルユーザーも使いやすいようにレスポンシブデザインの実装化


#ポートフォリオ作成のヒント

phpを学んでいたので、どうせだったらなにか作ってみたい！と思い、
https://www.techpit.jp　
でヒントになるものを探していました。探していた中で、PHPのフレームワークであるLaravelで作成できる「trello風todoタスク管理アプリ」を見つけ、素のPHPを用いて自力で作成できないかと思い、作成してみることにしました。


https://www.techpit.jp/p/laravel-trello-todo

上記のアプリを参考に、どのようにすれば同じようなものをPHP言語で実装できるか、学んだ内容のアウトプットとして作成しました。
（買わずにどこまでできるか試してみて、結局買っていません）

ヒントをありがとうございます！！


#まとめ
初めて作成したサービスです。
PHPのアウトプット＆ウェブサービス公開までの流れを掴むことができました。

さらに精進していきます！！


#修正箇所

- スマホ閲覧時に、フォントが小さい
  →完全レスポンシブではないのでご容赦ください。。。

- TOP画面（未ログイン時）に、ログインや新規登録のボタンがあった方が使いやすい。
　→画面中央に「新規登録」「ログイン」ボタンを設置（8/17修正済み）
- ログイン、新規登録の際にログイン保持がチェックを入れなくても30日になっていた。
　→pass_saveを変数指定していなかったのが原因。（8/18修正済み）

- メモ単体の削除時、ゴミ箱マークを押すと確認なく削除される。
　→リスト削除時と同様に、ゴミ箱マークを押すとアラートで確認後、削除の仕様に変更。（8/30修正済み）

- メモの編集アイコン「三」が、パッと見「編集」に見えない。
　→編集アイコン変更し、ユーザーがわかりやすいように配慮。(8/30修正済み)