業務システム屋が初めてWebアプリを作成しました。

#この記事について
業務システム3年の若輩エンジニアが、忘年会の余興支援Webアプリを作成しました。
初めてのWebアプリであったので、その時勉強したことをまとめています。

#作成したWebアプリについて
参加者にポイントを配布し、カジノのようにポイントを多くするゲームの支援アプリ。

###余興の内容

- アナログでミニゲームを行う。（ジェスチャーゲームなど）
- 参加者はミニゲームの結果を予想する。（何人目まで正しく伝わるかなど）
- 予想には、自身のポイントをベッドする。
- 予想的中者はベッドしたポイントが2倍になり返却される。逆に予想を外した人はポイントが没収される。
- ミニゲームを数回行い、ポイントの高い順から豪華景品をプレゼント！

##実装した機能
###参加者のログイン、ポイント、ランキング管理
![IMG_6523.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532785/1721cfe7-13da-e42c-6498-4098a310744a.png)

###ミニゲームの予想投票
![IMG_6530.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532785/977bc655-5ae8-edfa-1623-b44e8ad8e214.png)

###投票率、投票内容の内訳表示
![IMG_6526.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532785/a26aa356-eebf-2f1e-c4b4-93d78c9c6f02.png)　　　![IMG_6527.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532785/9343d855-1e12-3a72-635f-dff6cd056899.png)

###ミニゲーム結果の登録とポイント集計
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532785/7dc02483-56af-b628-eebf-f2d8a60ef594.png)　　　![IMG_6528.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532785/7c8fa7e1-55ad-30a4-a903-115199c52ffa.png)

###自身のポイントと平均ポイント推移のグラフ表示
![IMG_6529.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532785/6c507336-d905-479f-0429-44a4e9144581.png)


##デプロイ環境
レンタルサーバ－はロリポップ！を使用しました。
アプリの規模もとても小さく、フレームワークも使用していないので、上記で十分だと思いました。
そんなに技術力に自信がないよって人が、初めてWebアプリを公開するにはよかったです。
一点だけ確認不足だったのは、DBのバージョンです。ウィンドウ関数に対応する直前のバージョンでした。

（記事を書いている頃には、Paasについても少しづつ理解できるようになりました。
　イケているエンジニアであれば、最初にプラットフォームを選択し、その上にアプリを作るのでしょう。
　今回は、知見がなかったということもあり、プラットフォームの選択に重きを置けませんでした。
　次回に期待。）

###使用言語
ロリポップ！ではPHPが一番メインぽかったので、PHPを使用しました。
業務ではC#オンリーで、スクリプト言語自体が初めてでしたので、こだわりはなかったです。

（OOPについてがっつりと勉強してから、OOP言語の差はとても小さくなりました。
　それぞれの言語でモダンな書き方は勉強する必要がありますが、本質は同じってやつでしょうか。）

###使用DB
ロリポップ！ではMySqlが扱えます。
業務ではSQL Serverオンリーなので、こちらもお初です。
PHPからDBへのアクセスは、定石であろうPDOを使用しました。

（接続するたびにPDOインスタンスを生成しているので、オーバーヘッドが気になってました。
　上記の疑問をイケているエンジニアに尋ねると、コネクションプーリングというワードを引き出せました。
　そこから、MySqlの接続コストが低いことや、MySqlの最大同時接続数について調査することができ、
　コネクションプーリングは不要と判断しました。ありがとう、イケているエンジニア。）

##実装した機能の詳細について
###参加者のログイン、ポイント、ランキング管理
####ログイン
ログイン状態を維持するために、セッションやCookieについて学習しました。
セッションは有効期限を設けなければ、ブラウザを閉じるまで有効です。
しかし、ロリポップ！ではサーバー側の設定で、有効期限が設けられていました。
ロリポップのライトプランではphp.iniファイルは見られないのでしょうか。

（ちゃんとしたシステムでは上記を調べないなんて言語道断ですが、
　実際にアプリを使用する場では、30分以上の放置は起こりえないため、
　1時間弱の放置テストをして、不問にしました。）

####ポイント、ランキング管理
ランキング管理では、デプロイ環境で確認不足だったMySqlのバージョンがアダとなります。
本来であれば、ウィンドウ関数のRankを使用することでSQLのみで完結します。
しかし、ウィンドウ関数に対応していないバージョンのため、プログラムで付与する羽目になりました。
プログラム内でSQLを動的生成する場合、複雑に記述されていると発狂するので、注意したい部分です。

###ミニゲームの予想投票
ラジオボタンから選択し、投票しているだけの機能です。
単純な機能ですが、CSSを使用するだけで、モダンな感じ見えるのはWebのいい所です。
参考図書で紹介している本のなかで、ブラウザバックやダブルクリックによる二重登録の対応策について、
最も確実なワンタイムトークンを含め、複数の対応策を学習することができました。

###投票率、投票内容の内訳表示
Webアプリの構想時から、この機能についてはこだわりたいと思っていました。
初めは、CSSによる円グラフの表示から調べ、最終的にChart.jsに行きつきました。
高機能なライブラリをすぐに実装できるというは、気持ちがいいものです。

（素晴らしいフレームワークやライブラリを使えるようになると、自分がイケてるエンジニアになったと
　錯覚しがちです。しかし、その恩恵を授かっているだけであることを、忘れてはいけません。）

###ミニゲーム結果の登録とポイント集計
ミニゲームの実施後に、ゲームマスターが答えを登録します。
答えを登録時に参加者のポイントも計算します。
次回以降の投票戦略の判断材料になるかと思い、変動値も載せています。

###自身のポイントと平均ポイント推移のグラフ表示
Chart.jsがあまりにも簡単実装だったため、調子にのって折れ線グラフでポイントの推移を実装しました。


##感想
アプリ作成は勉強になりました。特にWeb周りの知識は実装を行うことで、より着実に身に着けられました。
また、記事作成も勉強になりました。今度はOOPを身に着けた過程について記事を作成してみたいと思います。
プログラムの面ではより高度な実装に励みたいです。ただ、作りたいものが簡単に浮かばないところが壁です。

###参考図書
[「プロになるためのWeb技術入門」 ――なぜ、あなたはWebシステムを開発できないのか](https://www.amazon.co.jp/dp/4774142352/ACsFCb5P1K1T6)