PHPとVue.jsを使って「本のレンタルアプリケーション」を作成した話

##はじめに
**PHPとVue.js**を使った**「本のレンタルアプリケーション」**を作成した時の話や、構成をまとめてみました。
Web系のプログラミングを大方学んでみて、実際に何か作ってみようと考えている人や、複数のプログラミングや技術を合わせて使ったことのない人に参考にしていただければと思います。
PHPとVue.jsでなくても、RubyやjQueryなどでも代用はできますし、どちらかといえば環境構築やデータベースの構成のほうをメインに書いています。

##図書レンタルアプリを作った理由
今回この図書レンタルアプリを作ろうと思ったのは、一から一人だけで、サービスを作る経験を積んでおきたかったからです。
業務では基本的に分業が多く、フロントエンドとバックエンドで別れてサービスを構築するのが基本で、新しくサービスを一から作る機会自体少ないです。
基本は現状あるサービスの改修や、修正がメインのため、一からサービスをコンスタントに作って、場数を踏みたいと思ったのがきっかけです。
そして何を作ろうかと考えたときに、会社の本棚の本の管理ができていなかったので、誰が何をいつまで借りているのかや、本のレンタル履歴を管理できるアプリケーションを作ってみようと思ったのがきっかけです。

##使用した技術

|使用した技術|
|--|
|PHP|
|Vue.js|
|MySQL|
|Docker|

##アプリを作り始めた時の自分のスキルレベル

###javascript
javascriptは実務でもメインで使っているため、問題なくかけるレベルです。
ライブラリーやフレームワークにつては、jQueryとVue.jsが使えました。
jQueryは結構知識はありましたが、Vue.jsの経験は少なめでした。

###Vue.js
Vue-CLI、vue-router、VueXの基礎知識をudemyの動画を通して学んだくらいです。
仕事ではVueファイル形式で書いたことはなく、今回Vueファイル形式で、ビルドする書き方ははじめてでした。

###PHP
PHPも実務での経験は少なく、PHPで一からサービスを作ったことはありませんでした。
実務で、今あるサービスの改修や修正、機能追加などでPHPを触るくらいの経験しか有りませんでした。

###Docker
Docker関しては、完全に初めてで、素人でした。
それまではVirtualBoxでlinuxの環境を作って、開発を行っていました。
なのでlinuxコマンドなどの知識はある前提です。

###スキルレベルのまとめ
一応現役のエンジニアではありますが、基本的に一からのサービス構築の経験は少なく、あってもメインで携わって来たのはフロント側のみで、バックエンドやインフラはすでに構築されているものを少し触るくらいの経験しか積んできませんでした。
キャリア的にももっと経験を積まないとまずいと思い、ここらで一気に経験を積みたいと思い、とりあえず「PHP」「Vue.js」「MySQL」「Docker」この辺の技術を使って、一人で一から簡単なサービスを作るところから始めようと思いました。


##図書レンタルアプリの機能
バックエンドとユーザー登録、ログインのページはPHP
それ以外のフロントエンドはVue.jsで作成しました。

###実装する機能のリスト
・ユーザー登録機能
・ログイン機能
・ログアウト機能
・レンタル機能
・レンタル状況確認機能
・返却機能
・返却期限編集機能
・ユーザー情報編集機能
・ランキング機能
・本の登録機能

##アプリのデザインについて
普段の業務で自分であまり使わないのですが、デザインを作成するのにXDを使い、簡単にデザインを作成しました。
今回はXDのスキルではなく、Web開発のエンジニアスキルを高めたかったので、デザインはなるべくシンプルにしました。
もともとミニマムなデザインが好きなので、色もモノトーンベースにしています。
###PHPで作成した「ユーザー登録ページ」と「ログインページ」
<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367456/eeb636f7-a43d-d63d-ced9-0c97f3d7c17b.png">　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367456/70dfb9d9-514a-41b6-cc1f-8f969d49f929.png">　

###Vue.jsで作成したシングルページアプリケーション（SPA）
<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367456/11466358-139c-b426-5e76-f4b602361d56.png">　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367456/584f65dc-2161-a1c3-cabd-f1d8700537eb.png">　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367456/3a186a45-e9f6-a06d-3988-36181594e5a5.png">

##データベースについて
**データベースはMySQLを使用しました。**
MySQLにlibraryというデータベースを作成し、その中に「**members**」「**book**」というテーブルを作成しました。
###データベースの構成と役割
データベース：library
　 テーブル
　　└book
　　└members
![グループ 83.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367456/657c3837-7a88-2d9e-158b-8a8aa936bcd7.png)
####book
**bookには本の情報を保存します。**
book_id：本を識別するID
title：本のタイトル
status：本がレンタル中or在庫あるか
rental_id：レンタルされている場合はmemberのid、レンタルされていない場合はNULL
date_rimit：レンタルされている場合はレンタル期限、レンタルされていない場合はNULL
category：本のカテゴリー
tag：本の検索に使うtag
count：レンタルされた回数
created_at：本が登録された日付
####members
**membersにはアプリを使用する人のログイン情報や、レンタルしている本のidのリストを保存します。**
id：ユーザーを識別するID
name：ユーザーの名前
mail：ユーザーのメールアドレス
password：ログインするためのパスワード
created：ユーザー登録した日付
rental_list：現在レンタルしている本のbook_idのリスト

###各ファイルの役割

##PHPについて
PHPで**CRUD機能**を実装しました。
ユーザーの登録機能（Create）
ユーザのログイン機能（Read）
ユーザー、本の管理機能（Read）
ユーザー、本の情報書き換え（Update）

※Dleteに当たる機能は今回有りませんでした。

Vue.jsで作成したSPAから、本を検索したり、レンタルしたりするときにPHPを動かす必要がありますが、axiosを使い通信を行いました。

##Vue.jsについて
※この話はVue.jsを学んでいる人ならわかると思いますが、Vue.jsに興味がない場合は飛ばしてください
Vuejsで作成したSPAのページはタブ構成になっており、タブの切替はVue-routerを使って、urlを切り替えてタブ機能を実装しています。
各タブの中のページの切り替え（例えば、レンタルタブの中で、本を検索したり、本をレンタルする際にページの切り替え）は、動的コンポーネントで表示を切り替えています。
###レンタルタブ
<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367456/11466358-139c-b426-5e76-f4b602361d56.png">　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367456/97e44f99-765b-eda2-1e6b-c84afdfa7a26.png">　　<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367456/584f65dc-2161-a1c3-cabd-f1d8700537eb.png">

###状況タブ（レンタル状況と返却）
<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367456/d8755ba1-364e-5d32-ba53-c1ab4e63b50b.png">


##Dockerでの環境構築
今回は開発環境としてはDockerでLAMP環境を構築することにしました。
Docker-composeを使って、複数のコンテナをたててLAMPを構築しました。
参考までにymlファイルと、dockerファイルを公開しておきます。

```yml:yml
version: "3.7"
services:
  mysql:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "password"

  phpmyadmin:
    depends_on:
      - mysql
    image: phpmyadmin/phpmyadmin
    environment:
      PMA_HOST: mysql
    restart: always
    ports:
      - "8080:80"

  php-apache:
    build: ./php
    volumes:
      - ./htdocs:/var/www/html
    restart: always
    ports:
      - "80:80"
    depends_on:
      - mysql
volumes:
  db_data: {}
```

./phpの直下に下記を保存

```dockerfile:dockerfile
FROM php:7.3-apache
COPY ./php.ini /usr/local/etc/php/
COPY ./apache2.conf /etc/apache2/
COPY ./sites/*.conf /etc/apache2/sites-available/

RUN apt-get update \
  && apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev \
  && docker-php-ext-install pdo_mysql mysqli mbstring gd iconv
```

上記のファイルで下記のコマンドを実行すれば、LAMP環境が立ち上がります。

```terminal:terminal
docker-compose up -d
```

##Dockerでの環境構築で困ったこと
今回一番困ったのがDockerで作ったapacheの設定です。
私も初めて知ったのですが、公式で公開されている「php:7.3-apache」などのApacheは、あくまでphpが動くだけのapacheの環境しか用意していないため、普通のapacheの環境でデフォルトで設定されているようなものは、デフォルトで入っていないことがあります。
今回ハマったのが、Rewriteのモジュールです。
Vue-routerを使った時に、historyモードを使用していると、リロードした時に404エラーが出てしまいます。これはVueの公式にも記載されています。
それを回避するために、apacheの設定ファイルか、.htaccessでRewriteの設定をする必要があるのですが、そのためのモジュールがapacheにはありませんでした。
それに気づかずに、設定ファイルにRewriteの記述を書いても問題が解決せずにいました。
今回の場合は、それをphp:7.3-apacheに入り、インストールして解決しましたが、本来であれば、Dockerfileにそれを記載しておく必要があります。
そうしないと次回コンテナを新しく立ち上げた時に、また、同じことをしないといけないからです。
かなり勉強になりました。

##アプリケーションを作ってみた感想
今回一番新しい試みだったのが、Vue.js（Vuex、Vue-router）とDockerでの開発でしたが、初めてだったので、ディレクトリ構造などが少し納得できるくらい整理ができず、本当は記事にして、詳細まで説明しようと思っていたのですが、できませんでした。
ただ、一度作ってみることで、ディレクトリ構造以外にも、設計やデータベースの構成など、ワンストップで開発しないと経験できないことを多く学ぶことができました。
やはり部分的に開発しているだけでは、見えていないことや、自分のスキルとして足りていないことが多くあることを発見でき、やってみてよかったと思いました。

##AWSの使用について（余談）
ちょっと今回の話に関係ないののですが、少し話をさせてください。
このアプリを作る際に、本番のアップロード先について最初はAWSで、VPCとEC2を使ってネットワークとサーバーを立てて、そこで公開しようと思っていました。
ですが、この手のアプリケーションを作る時に、流行っているからというだけでAWSを使うのはちょっと違うと考えました。
特に初学者の人は手を出しやすい場所だと思うのですが、AWSは基本的に従量課金のため、サーバーが動いている分だけ料金が課金されていきます。
lamdaなどを使って、アプリケーションが動くときだけ稼働させるなどの工夫をすればいいのですが、割と初学者にとってはハードルが高いため、最初はおすすめしません。
もちろんAWSの技術をみにつける目的があるのであれば、試すのもありですが、今回はインフラ周りというよりも動くものを作るのが目的だったので、さくらサーバーなどのレンタルサーバーを使用しました。
というのも会社で使うアプリケーションのため、サーバーやAWSは会社のものを使うので、コストは最小限に抑える必要があったからです。
プログラミングを学ぶときにはこういったコストのことも考えながら作ると、より実践向きのエンジニアに成長できると思うので、今回関係ないですが、この話をはさみました。