PHP で入力フォームの値を Cookie に保持する

はじめに

実務にて、前回送信した入力フォームの値を保持してほしいという小仕事の依頼があり、それを解決した情報になります。ソースコードをコピペ(コピー&ペースト)するだけで簡単に流用ができます。盗聴や改竄をされて困る機微情報を取り扱う場合は、Session の利用を推奨します。

ソースコード

<?php
const BLOODS = [
  'A',
  'B',
  'O',
  'AB'
];

const GENDERS = [
  '男',
  '女'
];

const HOBBIES = [
  '映画鑑賞',
  'アニメ鑑賞',
  'スキューバダイビング',
  'ベースギター'
];
?>

<form action="cookie.php" method="post">
  <ul>
    <li>
      名前:
      <input type="text" name="name" size="40" maxlength="40" value="<?= $_COOKIE["name"] ?>">
    </li>
    <li>
      血液型:
      <select name="blood">
        <?php foreach (BLOODS as $blood): ?>
          <option value="<?= $blood ?>" <?= $blood === $_COOKIE['blood'] ? 'selected' : '' ?>><?= $blood ?>型</option>
        <?php endforeach; ?>
      </select>
    </li>
    <li>
      性別:
      <?php foreach (GENDERS as $gender): ?>
        <input type="radio" name="gender" value="<?= $gender ?>" <?= $gender === ($_COOKIE['gender'] ?? '男') ? 'checked' : '' ?>>
        <?= $gender ?>
      <?php endforeach; ?>
    </li>
    <li>
      趣味:
      <?php foreach (HOBBIES as $hobby): ?>
        <input type="checkbox" name="hobby[]" value="<?= $hobby ?>" <?= in_array($hobby, (array)json_decode($_COOKIE['hobby']), TRUE) ? 'checked' : '' ?>>
        <?= $hobby ?>
      <?php endforeach; ?>
    </li>
    <li>
      コメント:<br>
      <textarea name="comments" rows="2" cols="40"><?= $_COOKIE['comments'] ?></textarea>
    </li>
    <input type="submit" value="送信">
  </ul>
</form>
<?php
$expires = time() + 24 * 3600;

setcookie('name', $_POST['name'] ?? '', $expires, '/');
setcookie('blood', $_POST['blood'] ?? '', $expires, '/');
setcookie('gender', $_POST['gender'] ?? '', $expires, '/');
setcookie('hobby', json_encode($_POST['hobby'], JSON_UNESCAPED_UNICODE) ?? '', $expires, '/');
setcookie('comments', $_POST['comments'] ?? '', $expires, '/');
?>

<p>クッキーを保存しました!</p>
<a href="index.php">戻る</a>

検証環境

解説

フォームデータの送信後、PHP の setcookie() メソッドで Cookie を作成します。

<?php
$expires = time() + 24 * 3600;

setcookie('name', $_POST['name'] ?? '', $expires, '/');
setcookie('blood', $_POST['blood'] ?? '', $expires, '/');
setcookie('gender', $_POST['gender'] ?? '', $expires, '/');
setcookie('hobby', json_encode($_POST['hobby'], JSON_UNESCAPED_UNICODE) ?? '', $expires, '/');
setcookie('comments', $_POST['comments'] ?? '', $expires, '/');
?>

checkbox の値は配列になっています。その場合は、json_encode() メソッドで JSON 形式にして設定すると簡単です。

setcookie('hobby', json_encode($_POST['hobby'], JSON_UNESCAPED_UNICODE) ?? '', $expires);

$_COOKIE から取り出す際は、json_decode() メソッドでデコードします。

<?= in_array($hobby, (array)json_decode($_COOKIE['hobby']), TRUE) ? 'checked' : '' ?>

また、Cookie は次にページをロードするまでアクセスすることができないので注意しましょう。

$_COOKIE を参照して各 フォーム入力要素 の value 属性、或いは checked 属性を設定するだけです。

以上です。

おわりに

今回は、盗聴や改竄をされても特に問題ないデータだったので Cookie を利用しました。機微情報を取り扱う場合は Session を利用します。

CookieSession の違いですが、Cookie はクライアントのブラウザに保存されるのに対して、Session はブラウザとサーバーに保存されます。できるだけサーバーへの負荷を軽減させたい場合は、Session だけでなく Cookie の利用も検討すると良いです。