php スクラッチでecサイトを作ってみた

## 前提・実現したいこと
近年、アマゾンや楽天のようなECサイトが普及してきており、それらのサイトの裏の動き（裏のプログラム）はどのようになっているか全体像を把握することに努め、これまでに作ってきた「お問い合わせフォーム」や「管理画面」、「ログイン画面」で学んだことをECサイトを作ることで、総復習していきたいと思いサイト作成に取り掛かった。またフレームワークは一切使わず、スクラッチでサイトを作成している。

## 作成する物の概要
作成するものの要素としては、以下の７つ
1. ユーザーの新規作成フォーム
2. 商品の登録フォーム
3. ログイン画面
4. 商品の一覧画面
5. 商品の詳細画面
6. カート画面
7. 決済画面
### 1.ユーザーの新規作成フォーム
- 名前
- 住所
- メールアドレス
- パスワード
- クレジットカード
を入力してもらい各項目ごとにバリデーション機能をつけた。
ポイントとしてはメールアドレスの重複登録を避けるため、次のような関数を作った。

## 該当のソースコード
```.php
function email_dupli($email){
    try{
        $dsn = 'mysql:dbname=myapp;host=localhost;charset=utf8';
        $username = 'toshiki';
        $pass = 'fumiya1118';
        $options = array(
        // SQL実行失敗時にはエラーコードのみ設定
        PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT,
        // デフォルトフェッチモードを連想配列形式に設定
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        // バッファードクエリを使う(一度に結果セットをすべて取得し、サーバー負荷を軽減)
        // SELECTで得た結果に対してもrowCountメソッドを使えるようにする
        PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
    );
    //connect
        $dbh = new PDO($dsn, $username, $pass, $options);
        //connect
        $dbh-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $query = $dbh->prepare('SELECT * FROM users WHERE email = :email limit 1');
        $query->execute(array(':email' => $email));
        $result = $query->fetch();
        if($result > 0){
            return True;
        }
    }catch(PDOException $e){
        echo $e-> getMessage();
        exit;
    }
}
```
データベースに入力されたメールアドレスをいれ、結果が何か返ってきたらTrueとした。

### 2.商品の登録フォーム

1. と同様商品URLに重複がないよう、重複防止の関数を設置した
2. 
### 3.ログイン画面

```.php
      $stmt = $db->prepare('select id from users where email=? and password=? ');
      $stmt->execute(array($email, $password));
      $users = $stmt->fetch();
      $stmt=null;
      $db=null;
      if($users != false){
          $_SESSION['id']=$users['id'];
          header('Location: product/product_list.php');
          exit;
      }else{
          $err="・ユーザー名またはパスワードに誤りがあります";
      }
```

メールアドレス、パスワードをデータベースに投げ、結果がTRUEならば商品画面に遷移しそれ以外ならばエラーを表示させた。またユーザーのIDをセッションに格納した。

### 4.商品の一覧画面
2.で登録した商品を一覧として表示させた。各商品の下に「Detail」ボタンをつけ、ボタンが押されたら各商品IDを次の画面にPOSTしている。

### 5.商品の詳細画面

4.で送られてきた商品IDをもとにその商品の情報を表示させ個数を選択できるようにし「カートに入れる」ボタンを付け、商品の個数、商品IDをセッションに格納した。またセッションに配列で順次追加していくことがこのECサイト制作で最も難しいところだったので、その部分のコードを載せておく。

```.php
      $num = filter_input(INPUT_POST,"num");
      if(isset($_SESSION['data'][$productId])){
          $_SESSION['data'][$productId] += $num;
      }else{
          $_SESSION['data'][$productId] = $num;
      }
```
ポストで送られてきた商品ID（productId）、数(num)を上記のように追加していった

### 6.カート画面
$_SESSION['data'][$productId]は連想配列で入っているので、データを取り出し、小計、合計金額を表示するようにした。

### ７.決済画面
セッションに入っているユーザーのIDから、ユーザー名、住所、クレジットカードをデータベースから取り出し、最後に合計金額を表示させた。
また正規化したデータベースにデータを詳細に登録していった。各データベースのテーブルを以下に載せる。

```
`users` (
  `id` int(11) NOT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `adress` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `email` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `password` char(30) COLLATE utf8_unicode_ci DEFAULT NULL,
  `credit` char(30) COLLATE utf8_unicode_ci DEFAULT NULL
)
`products` (
  `productId` int(11) NOT NULL,
  `item_name` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `item_img` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `introduce` text COLLATE utf8_unicode_ci,
  `price` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
)
 `orders` (
  `id` int(11) NOT NULL,
  `userId` int(11) DEFAULT NULL,
  `total` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `adress` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `credit` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `status` int(11) DEFAULT '1'
)
`orders_detail` (
  `id` int(11) NOT NULL,
  `orderId` int(11) DEFAULT NULL,
  `productId` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  `num` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL
)
```
## 重視したこと
今回のサイト作成は今までよりもサイトマップが複雑複雑なので実際に全体構造を具現化し、それぞれの要素に必要な物を細かく図や文章にして実装していく必要がある。またユーザーが利用することも想定し、bootstrapを用いてレイアウトを整えた。
## 補足情報（FW/ツールのバージョンなど）
PHP 7.3.5
mysql  15.1
bootstrap 4.3.1