【PHP／MySQL】クッキーをWebサイトに食べさせる。

前回の記事で、SQLを組み込んだホームページを全世界に公開しました。
そのあと、まだ試しておく事が沢山ありますので、順次対応します。
本日はクッキーの設定です。
前回の記事のソースを修正していきます。

https://qiita.com/ishikawaryou/items/938e14ad5cd7c4c2dfd5

 #  １.イメージ

taiju.php、writetaiju.phpの2つのソースを修正します。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/09898f9d-b0e3-787f-a9e7-13409a55aa11.png)



 #  ２.実装


「クッキーを読み込んでフォームの名前を設定する from」「クッキーを読み込んでフォームの名前を設定する to」のコメントでくくられた所が修正対象です。

 #  (1).書き込み処理

```writetaiju.php
<?php
  // データの受け取り
  $title = $_POST['title'];
  $taiju = $_POST['taiju'];
  $memo = $_POST['memo'];

  // 必須項目チェック（体重が空ではないか？）
  if ($taiju == ''){
    header("Location: taiju.php");  // 空のときtaiju.phpへ移動
    exit();
  }

  // 必須項目チェック（体重は3桁の数字か？
  if (!preg_match("/^[0-9]{3}$/", $taiju)){
    header("Location: taiju.php");  // 書式が違うときtaiju.phpへ移動
    exit();
  }

  // 名前をクッキーにセット 2024/02/25 from
  setcookie('memo',$memo,time() + 60*60*24*30);
  // 名前をクッキーにセット 2024/02/25 to


  // DBに接続：Webサーバー
  $dsn = 'mysql:host=mysql212.phy.lolipop.lan;dbname=*********-test;charset=utf8';
  $user = '*******';
  $password = '********'; // tennisuserに設定したパスワード


  // DBに接続
  //$dsn = 'mysql:host=localhost;dbname=tennis;charset=utf8';
  //$user = 'tennisuser';
  //$password = 'password'; // tennisuserに設定したパスワード

  try {
    // PDOインスタンスの作成
    $db = new PDO($dsn, $user, $password);
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    // プリペアドステートメントを作成
    $stmt = $db->prepare("
      INSERT INTO taiju(title,taiju,memo)
      VALUES (:title, :taiju,:memo)"
    );
    // プリペアドステートメントにパラメータを割り当てる
    $stmt->bindParam(':title', $title, PDO::PARAM_STR);
    $stmt->bindParam(':taiju', $taiju, PDO::PARAM_STR);
    $stmt->bindParam(':memo', $memo, PDO::PARAM_STR);
    // クエリの実行
    $stmt->execute();

    // taiju.phpに戻る
    header('Location: taiju.php');
    exit();
  } catch (PDOException $e){
    exit('エラー：' . $e->getMessage());
  }
?>
```

ここで、DBに登録する値であるmemoを、クッキーにセットします。
有効期限は1か月。秒単位で表現するみたいですね。

```
  // 名前をクッキーにセット 2024/02/25 from
  setcookie('memo',$memo,time() + 60*60*24*30);
  // 名前をクッキーにセット 2024/02/25 to
```


 

 #  (2).読み込み・ページ表示処理

```taiju.php
<?php

  // クッキーを読み込んでフォームの名前を設定する from
  if (isset($_COOKIE['memo'])){
    $memo = $_COOKIE['memo'];
  } else {
    $memo = "";
  }
  // クッキーを読み込んでフォームの名前を設定する to


  // 1ページに表示される書き込みの数
  $num = 10;
  $test = 'abcd';

  // DBに接続：Webサーバー
  $dsn = 'mysql:host=mysql212.phy.lolipop.lan;dbname=********-test;charset=utf8';
  $user = '********';
  $password = '*******'; // tennisuserに設定したパスワード

  // DBに接続：ローカル
  //$dsn = 'mysql:host=localhost;dbname=tennis;charset=utf8';
  //$user = 'tennisuser';
  //$password = 'password'; // tennisuserに設定したパスワード


  // GETメソッドで2ページ目以降が指定されているとき
  $page = 1;
  if (isset($_GET['page']) && $_GET['page'] > 1){
    $page = intval($_GET['page']);
  }

  try {
    // PDOインスタンスの生成
    $db = new PDO($dsn, $user, $password);
    $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    // プリペアドステートメントを作成
    $stmt = $db->prepare("SELECT * FROM taiju ORDER BY title DESC LIMIT :page, :num");
    // パラメータを割り当て
    $page = ($page-1) * $num;
    $stmt->bindParam(':page', $page, PDO::PARAM_INT);
    $stmt->bindParam(':num', $num, PDO::PARAM_INT);
    // クエリの実行
    $stmt->execute();
  } catch (PDOException $e){
    exit("エラー：" . $e->getMessage());
  }
?>
<!doctype html>
<html lang="ja" >
  <head>
    <title>体重っち</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
  </head>
  <body>

    <!--
    <?php include('navbar.php'); ?>
    -->

    <main role="main" class="container" style="padding:60px 15px 0">
      <div>
        <!-- ここから「本文」-->

        <h1>体重メモ</h1>
        <form action="writetaiju.php" method="post">


          <div class="form-group">
            <label>日付（YYYYMMDD）</label>
            <!--
            <input type="date" name="title" class="form-control">
    	    -->
            <input type="text" name="title" class="form-control">
          </div>

          <div class="form-group">
            <label>体重</label>
            <input type="text" name="taiju" class="form-control">
          </div>
          <div class="form-group">
            <label>メモ（思った事など）</label>
            <!--
            <input type="text" name="memo" class="form-control">
    	    -->
            <!-- クッキーを読み込んでフォームの名前を設定する from-->
            <input type="text" name="memo" class="form-control" value="<?php echo $memo ?>">
            <!-- クッキーを読み込んでフォームの名前を設定する from-->
          </div>
          <input type="submit" class="btn btn-primary" value="書き込む">
        </form>
        <hr>

<?php while ($row = $stmt->fetch()): ?>
        <div class="card">
          <div class="title-body">
            <!--17:58 2024/02/04 エスケープ対応修正 from -->
            <p class="card-title"><?php echo htmlspecialchars(nl2br($row['title']), ENT_QUOTES, "UTF-8") ?></p>
            <!--<p class="card-title"><?php echo nl2br($row['title']) ?></p>-->
            <!--17:58 2024/02/04 エスケープ対応修正 to -->
          </div>
	</div>
        <div class="card">
          <div class="taiju-body">
            <p class="card-taiju"><?php echo nl2br($row['taiju']) ?></p>
          </div>
        </div>
        <div class="card">
          <div class="memo-body">
            <!--17:58 2024/02/04 エスケープ対応修正 from -->
            <p class="card-memo"><?php echo htmlspecialchars(nl2br($row['memo']), ENT_QUOTES, "UTF-8") ?></p>
            <!--<p class="card-memo"><?php echo nl2br($row['memo']) ?></p>-->
            <!--17:58 2024/02/04 エスケープ対応修正 to -->

          </div>
        </div>
        <hr>
<?php endwhile; ?>

<?php
  // ページ数の表示
  try {
    // プリペアドステートメントの作成
    $stmt = $db->prepare("SELECT COUNT(*) FROM taiju");
    // クエリの実行
    $stmt->execute();
  } catch (PDOException $e){
    exit("エラー：" . $e->getMessage());
  }


  // 書き込みの件数を取得
  $comments = $stmt->fetchColumn();
  // ページ数を計算
  $max_page = ceil($comments / $num);
  // ページングの必要性があれば表示
  if ($max_page >= 1){
    echo '<nav><ul class="pagination">';
    for ($i = 1; $i <= $max_page; $i++){
// ここを修正しないと、更新後に戻ってくるページがtaiju.phpではなくなる。
      echo '<li class="page-item"><a href="taiju.php?page='.$i.'">'.$i.'</a></li>';
    }
    echo '</ul></nav>';
  }
?>

        <!-- 本文ここまで -->
      </div>
    </main>

    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" crossorigin="anonymous"></script>
    <script>window.jQuery || document.write('<script src="/docs/4.5/assets/js/vendor/jquery-slim.min.js"><\/script>')</script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.bundle.min.js"></script>
  </body>
</html>
```

ここでクッキーを読み込み、isset関数で変数$memoに値を設定します。


 ```
 // クッキーを読み込んでフォームの名前を設定する from
  if (isset($_COOKIE['memo'])){
    $memo = $_COOKIE['memo'];
  } else {
    $memo = "";
  }
  // クッキーを読み込んでフォームの名前を設定する to
```


こちらで、value値にクッキーが設定された$memoを初期表示しています。

            <!--
            <input type="text" name="memo" class="form-control">
    	    -->
            <!-- クッキーを読み込んでフォームの名前を設定する from-->
            <input type="text" name="memo" class="form-control" value="<?php echo $memo ?>">
            <!-- クッキーを読み込んでフォームの名前を設定する from-->


 #  ３.結果

まず、「cookieメモ」と入力して登録。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/f7dd3427-7bb5-46a6-f9bd-0c2c1f0ff1da.png)

画面を開くと・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/6d43bfad-0f9c-91bd-202e-a66fbd697f80.png)

画面に「cookieメモ」と初期表示。


 #  ４.終わりに

思ったより簡単に済んでしまったので、次はセッションの動きを試してみます。