自作Webサービス -SHAKYO- 　FWを使用せず素のPHPで制作しました

##はじめに

フロントエンドエンジニアを目指してプログラミングを学習しています。
トンテキと申します。
プログラミング学習のアウトプットとして自作のWebサービス-SHAKYO-を制作、公開しました。
この記事では-SHAKYO-の概要や制作過程について説明します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/4b8cdcb7-1e85-ad44-a4dd-3f38fc08b49a.png" width="70%">
##URL

リンク先はこちら[- SHAKYO -](https://shakyo.t-w-d.com)






##目的

・フルスクラッチ開発を行うことでWebアプリの基本的な構成、動作を知る
・自作のWebアプリで同じ初学者の方の役に立つサービスを提供したい


##スペック
使用言語 / HTML５/ CSS3 / Javascript / PHP

DBMS / MySQL

開発環境 / MacOS Mojave 10.14.6

バージョン管理 / SourceTree(3.0.15)
  
本番環境 /  xserver


##主な機能
#### ユーザー管理機能
　・ユーザー登録機能
　・ユーザーログイン機能
　・ユーザー編集機能
　・ユーザー削除機能

#### LPサイト登録管理機能
　・LPサイト登録
　・LPサイト編集
　・LPサイト詳細
　・LPサイト一覧（ページネーション）
　・LPサイト検索機能（難易度選択機能）
　
#### LPサイト詳細機能
　・LPサイト詳細表示
　・LPサイトへのリンク
　・お気に入り機能
　・掲示板機能（メッセージ投稿）



##概要
-SHAKYO-は、写経・模写用のLPサイトを紹介するWebサービスです。

私自身LP写経・模写に挑戦する際、まずサイトを探すのに時間がかかったり、いざ初めて見ると難しく挫折しそうになっていました。

LPを集めたサイトはあるけれど、模写に適した初心者向けのLPだけを集めたサイトは無いな、あったらいいなと考えていました。

そしてPHP学習のアウトプットとして同じプログラミング初学者の時間短縮になればと思いこのWebサービスを作りました。

・誰でも気軽に利用できるようにゲストログイン機能の実装
・LP模写について進め方のコツや感想の情報交換ができるようにコメント機能を実装しています


##開発手順




###1.データベース設計

実装させたい主な機能から必要な項目を洗い出し、サンプルとしてExcelに必要なDB情報を書き出していきました。
洗い出した情報を元にテーブルを作成します。

Excel一例
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/8531353d-17fe-7334-eb3f-2f4f05b41f3d.png" width="">

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/33bc238b-0d03-5669-438d-157bfadf33c8.png" width="">


###2.AdobeXDデザインカンプ作成
プログラミング学習者の多くは20代〜30代前半と想定
キーワードは、ノマドフリーランス、モダンな会社
イメージとして若い人が使う、オシャレで無○良品のようにシンプルな雰囲気の仕上がりを目指しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/b90eba42-6d43-307b-029e-51b7c87fad58.jpeg" width="">



###3.モバイルファーストに合わせたレスポンシブ対応

またモバイルファーストに従いレスポンシブ対応させています。

プログラミングの学習報告はTwitter上での発信も多く、LPの写経や模写はSNSユーザーの間で認知されている学習方法です。

Twitterの報告ではユーザーの80％以上はモバイル端末からTwitterにアクセスしているとあります。

※ 補足：Twitter内部データ
https://business.twitter.com/ja/targeting/device-targeting.html

スマートフォンからの閲覧が大多数であればレスポンシブ化は必須と判断し、作成当初よりレスポンシブ対応で制作を進めていきました。

公開後、実装したGoogleアナリティクスによる分析で__アクセス元の77％はスマートフォンデバイス__からという結果が得られレスポンシブ対応は必須であったことが証明されました。


###4.コーディング
デザインカンプを元に画面モックを作成
その後裏側の機能を実装していきます


###5.xserverデプロイ
ドメインをxserverで取得
ローカル環境からDBのエクスポート
xserverのMySQLへインポート
公開後のテストを行いました




##セキュリティ対策

###バリデーションチェック
####サーバーサイド(PHP)側
　☑︎未入力チェック
　☑︎最大、最小文字数チェック
　☑︎半角英数字チェック
　☑︎正規表現を使用したemail型式チェック
　☑︎正規表現を使用したURL型式チェック
　☑︎同値チェック
　それぞれ関数を作成し各フォームで判定を行なっています。
以下一部抜粋です
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/4974e85e-1294-eb6e-25d9-d7fe6850b4f7.png" width="80%">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/75802ada-242c-ae40-65c2-8be4a4450b6a.png" width="80%">

####フロントエンド(HTML)側

URL型式チェックでは入力フォームをtype="url"とすることでHTMLで型式チェックができるようにしています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/f8db3cfa-3a35-ed84-0df2-71aaf0681e3f.png" width="80%">
![スクリーンショット 2019-09-04 10.40.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/f560c191-2fdc-60ff-6b1e-edb3f9fdab82.png)



###なりすまし対策について
セッションハイジャックによるなりすまし対策としてsession_regenerate_id関数を使用しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/fc6b42e5-c5da-6933-3624-50e03396986b.png" width="80%">
session_regenerate_id関数は、現在のセッションのデータを保持したまま、セッションIDを新しく生成してくれます。

※[セッションIDの再生成](https://www.84kure.com/blog/2014/08/12/php-%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E4%BD%BF%E3%81%84%E6%96%B9/)


###パスワードのハッシュ化について

パスワードをDBで登録する際は開発環境から見えてしまうのでセキュリティ上よくありません。
SHAKYOでは[password_hash](https://www.php.net/manual/ja/function.password-hash.php)関数でパスワードをハッシュ化してDB登録しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/01167efc-91d2-ed84-b3f1-49a85619205b.png" width="80%">





ログイン時には、 
[password_verifi](https://www.php.net/manual/ja/function.password-verify.php)を使用し、ハッシュ化されたパスワードを確認しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/9d1157a6-a38e-0eca-17f5-b893e0e93223.png" width="80%">
このとき$passはフォームからpostされたパスワード
DBから配列形式で取り出した情報を$resultに詰め
array_shiftを使って先頭から要素を一つ取り出し第二引数としています。


###SQLインジェクション対策

DB接続時は、プレースホルダーを利用しSQL文を作成。
プリペアードステートメントを使うことでSQLインジェクション対策を行なっています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/cbeadbbe-6b81-ba01-d379-70051c79078d.png" width="80%">


###XSS（クロスサイトスクリプティング）対策
画面へ文字列や数値を出力する際は、htmlspecialchars関数を使いエスケープ処理を行なっています。

エスケープ処理とは特殊な文字を無害な文字に強制的に置き換える方法です
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/a53a8c6d-08d7-1d39-8ccd-145d0834ac4c.png" width="60%">



第二引数のエスケープにはいくつか種類がありますが最もエスケープ文字数の多いENT_QUOTESを使用しています。

※[エスケープ処理のためのhtmlspecialcharsの使い方](https://web-dev.xyz/php-htmlspecialchars/)

※[PDOで接続、SELECT、プリペアドステートメントとは（PHPでMySQLに接続）](https://qiita.com/tabo_purify/items/d1166236f3b03c7be60d)

###スパムメール対策
お問合せフォーム経由からのスパムメール対策に[reCAPTCHA v3](https://www.google.com/recaptcha/intro/v3.html)を実装しています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/5197770e-4afa-1bb6-55ef-e26b55d7dc25.png" width="80%">

reCAPTCHA v3から[私はロボットではありません]のチェックボタンがなくなりユーザーの負担なくセキュリティチェックを行うことができます。

※[PHPでGoogle reCAPTCHA v3を使ってみる](http://fuminori14.hatenablog.com/entry/2018/11/09/124748)





##-SHAKYO-で出来ること
####①LPサイトの登録・編集・マイページ機能
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/1577eedd-7b66-916b-fc18-8f141bea16e2.gif" width="">


LPサイトの登録ページでは、LPサイトの名前、難易度、URL、詳細コメント、LPの画像の登録が可能です。


画像登録にはjQueryを利用しドラック&ドロップでInputされるよう設定しています。

登録完了後はマイページに遷移し、きちんと登録できたことが確認できるようメッセージが表示されます。

マイページでは自身が登録したLPサイトの閲覧、編集、プロフィール編集、お気に入り登録したLPサイトの閲覧が可能です。




####②LPサイト詳細画面に、Ajax処理によるお気に入り登録機能、掲示板機能を実装


#####お気に入り機能について
LPサイト詳細画面では、LP画像右上のハートアイコンを押すことで
マイページのお気に入り一覧にLPサイトを登録できます。
こちらはAjaxを用いて実装しています。
![お気に入り機能.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/eca28800-e8c6-c76e-1ae8-d567f99e7ba3.gif)



#####掲示板機能について



LPサイトの進め方について気軽に質問できるように
掲示板機能を各詳細ページに実装しています。
1対1ではなく複数人で書き込めるようにしました。

まず掲示板自体が存在するかDB情報を確認。
無ければ新規作成します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/366e180c-7d1c-db76-78a3-373a09b477e8.png" width="80%">

もし既に掲示板情報があればメッセージのみ追加できるよう条件分岐させています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/62cbe6fe-63fb-b67f-1b93-02803177b4bc.png" width="80%">
また、アイコン表示もLPサイト登録者なら左にメッセージを表示、質問者は右側に表示するようにしています。
アイコンの表示は３パターン用意しました。
ユーザーが自分でアイコンを登録していた場合。
ユーザーアイコンが登録されていなかった場合。
ゲストログインの場合も親しみやすい人型アイコンを登録してあります。

![掲示板.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/410eece2-db8d-0b94-d2db-e6530684fb30.gif)

####③LP一覧・検索機能
　LP一覧ページにはページネーション、カテゴリ選択による難易度選択機能を実装しました。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/023881e0-270f-f237-5016-951b64c76e5e.gif" width="">


###ゲストログイン機能
SHAKYOでは誰でも気軽にLPサイトの閲覧ができるようにゲストログイン機能を実装しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/1e764183-9dc8-7d78-f022-f1de0bbd74cd.png" width="70%">

トップページのゲストログインボタンを押すことでguestuser.phpに遷移。
そこで予め登録しておいたゲストユーザーIDをセッションに詰め、有効期限をデフォルトの1時間に設定。
その後LP一覧ページへ飛ぶように設定しています。
また、ゲストユーザーアカウントではプロフィール編集機能・パスワード変更機能・退会機能を使えないようにしています。
見た目でもわかるようにボタンを押せないよう設定しています。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391439/6dc6ab44-6743-aed5-a3db-df452a8d0df9.png" width="70%">

##課題点

・掲示板機能にAjaxを実装し画面遷移を潤滑にする
・twitterアカウントでログイン機能を実装
・スマートなコードに書き換える
・Webマーケティングを学習し多くの人に利用、LP登録しもらえるよう改善する


以上です。
今後も学習を続け、より良いコードを書く、良いサービスを提供できるよう精進します。
フロントエンドエンジニアとして働きたいです！よろしくお願いします！