PHPでCSVを使った会員登録機能を作る方法【サンプルコード付き】

php

PHPでCSVを使った会員登録機能を作る方法

PHPとCSVを使って会員登録機能を作る方法を紹介します。氏名・メールアドレス・パスワードを登録し、CSVへ会員情報を保存できるサンプルです。メールアドレスの重複チェックや確認用パスワードの一致チェックに加え、パスワードは password_hash() によりハッシュ化して保存します。ログイン機能や会員専用ページを作る前の会員管理の基礎として利用できます。

コードについて 本記事のコードはサンプルコードです。ご利用前に必ず動作確認を行ってください。
免責事項 本コードの利用により発生した損害について、当サイトは一切の責任を負いません。

デモ

会員登録フォーム
会員登録が完了しました。

登録済み会員一覧

氏名 メールアドレス
山田 太郎 test@example.com
佐藤 花子 admin@example.com

コードをコピーして使おう!

<?php

$csv_file = 'users.csv';

$name = '';
$email = '';
$password = '';
$password_confirm = '';

$errors = [];

if ($_SERVER['REQUEST_METHOD'] === 'POST') {

    $name = trim($_POST['name'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $password = trim($_POST['password'] ?? '');
    $password_confirm = trim($_POST['password_confirm'] ?? '');

    if ($name === '') {
        $errors['name'] = '氏名を入力してください。';
    }

    if ($email === '') {
        $errors['email'] = 'メールアドレスを入力してください。';
    }

    if ($password === '') {
        $errors['password'] = 'パスワードを入力してください。';
    }

    if ($password_confirm === '') {
        $errors['password_confirm'] = '確認用パスワードを入力してください。';
    }

    if (
        $password !== '' &&
        $password_confirm !== '' &&
        $password !== $password_confirm
    ) {
        $errors['password_confirm'] = '確認用パスワードが一致しません。';
    }

    if ($email !== '') {

        if (file_exists($csv_file)) {

            $fp = fopen($csv_file, 'r');

            while (($row = fgetcsv($fp)) !== false) {

                if (
                    isset($row[2]) &&
                    strtolower($row[2]) === strtolower($email)
                ) {
                    $errors['email'] = 'このメールアドレスは既に登録されています。';
                    break;
                }

            }

            fclose($fp);

        }

    }

    if (empty($errors)) {

        $next_id = 1;

        if (file_exists($csv_file)) {

            $rows = file(
                $csv_file,
                FILE_IGNORE_NEW_LINES |
                FILE_SKIP_EMPTY_LINES
            );

            if (count($rows) > 1) {

                $last = str_getcsv(end($rows));
                $next_id = (int)$last[0] + 1;

            }

        }

        $fp = fopen($csv_file, 'a');

        fputcsv($fp, [
            $next_id,
            $name,
            $email,
            password_hash(
                $password,
                PASSWORD_DEFAULT
            )
        ]);

        fclose($fp);

        header('Location: '.$_SERVER['PHP_SELF'].'?success=1');
        exit;

    }

}

$users = [];

if (file_exists($csv_file)) {

    $fp = fopen($csv_file, 'r');

    while (($row = fgetcsv($fp)) !== false) {

        if (
            isset($row[0]) &&
            $row[0] === 'id'
        ) {
            continue;
        }

        $users[] = $row;

    }

    fclose($fp);

}

?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>会員登録機能</title>

<style>

body{
  margin:0;
  padding:30px;
  font-family:sans-serif;
  background:#fff;
}

.register-wrap{
  border:1px solid #e5e7eb;
  border-radius:20px;
  padding:24px;
  background:#fff;
}

.register-card{
  max-width:520px;
  margin:0 auto;
  padding:24px;
  border:1px solid #e5e7eb;
  border-radius:18px;
  background:#f8fafc;
}

.register-title{
  font-size:22px;
  font-weight:700;
  margin-bottom:20px;
}

.field{
  display:flex;
  flex-direction:column;
  gap:6px;
  margin-bottom:14px;
}

label{
  font-weight:700;
}

input{
  width:100%;
  box-sizing:border-box;
  padding:12px;
  border:1px solid #d1d5db;
  border-radius:10px;
}

.input-error{
  border-color:#dc2626;
  background:#fef2f2;
}

.field-error{
  color:#dc2626;
  font-size:13px;
  font-weight:700;
}

.btn{
  width:100%;
  height:46px;
  border:none;
  border-radius:10px;
  background:#0b6bff;
  color:#fff;
  font-weight:700;
  cursor:pointer;
}

.success{
  margin-top:16px;
  padding:14px;
  border-radius:12px;
  border:1px solid #e5e7eb;
  background:#fff;
  color:#15803d;
  font-weight:700;
}

table{
  width:100%;
  border-collapse:collapse;
}

th,
td{
  border:1px solid #e5e7eb;
  padding:10px;
  text-align:left;
}

th{
  background:#fff;
}

</style>

</head>
<body>

<div class="register-wrap">

  <div class="register-card">

    <div class="register-title">
      会員登録フォーム
    </div>

    <form method="post">

      <div class="field">
        <label>氏名</label>
        <input
          type="text"
          name="name"
          value="<?= htmlspecialchars($name, ENT_QUOTES, 'UTF-8') ?>"
          autocomplete="name"
          class="<?= isset($errors['name']) ? 'input-error' : '' ?>">

        <?php if(isset($errors['name'])): ?>
          <div class="field-error">
            <?= htmlspecialchars($errors['name'], ENT_QUOTES, 'UTF-8') ?>
          </div>
        <?php endif; ?>
      </div>

      <div class="field">
        <label>メールアドレス</label>
        <input
          type="email"
          name="email"
          value="<?= htmlspecialchars($email, ENT_QUOTES, 'UTF-8') ?>"
          autocomplete="email"
          class="<?= isset($errors['email']) ? 'input-error' : '' ?>">

        <?php if(isset($errors['email'])): ?>
          <div class="field-error">
            <?= htmlspecialchars($errors['email'], ENT_QUOTES, 'UTF-8') ?>
          </div>
        <?php endif; ?>
      </div>

      <div class="field">
        <label>パスワード</label>
        <input
          type="password"
          name="password"
          value="<?= htmlspecialchars($password, ENT_QUOTES, 'UTF-8') ?>"
          autocomplete="new-password"
          class="<?= isset($errors['password']) ? 'input-error' : '' ?>">

        <?php if(isset($errors['password'])): ?>
          <div class="field-error">
            <?= htmlspecialchars($errors['password'], ENT_QUOTES, 'UTF-8') ?>
          </div>
        <?php endif; ?>
      </div>

      <div class="field">
        <label>パスワード(確認)</label>
        <input
          type="password"
          name="password_confirm"
          value="<?= htmlspecialchars($password_confirm, ENT_QUOTES, 'UTF-8') ?>"
          autocomplete="new-password"
          class="<?= isset($errors['password_confirm']) ? 'input-error' : '' ?>">

        <?php if(isset($errors['password_confirm'])): ?>
          <div class="field-error">
            <?= htmlspecialchars($errors['password_confirm'], ENT_QUOTES, 'UTF-8') ?>
          </div>
        <?php endif; ?>
      </div>

      <button type="submit" class="btn">
        会員登録
      </button>

    </form>

    <?php if(isset($_GET['success'])): ?>
      <div class="success">
        会員登録が完了しました。
      </div>
    <?php endif; ?>

    <div style="margin-top:20px;">

      <h3 style="margin:0 0 12px;">
        登録済み会員一覧
      </h3>

      <table>
        <thead>
          <tr>
            <th>氏名</th>
            <th>メールアドレス</th>
          </tr>
        </thead>

        <tbody>

        <?php foreach ($users as $user): ?>
          <tr>
            <td><?= htmlspecialchars($user[1] ?? '') ?></td>
            <td><?= htmlspecialchars($user[2] ?? '') ?></td>
          </tr>
        <?php endforeach; ?>

        </tbody>
      </table>

    </div>

  </div>

</div>

</body>
</html>

ファイル構成と設置方法

このサンプルで使用するファイル構成です。
下記のファイルを同じフォルダ(同じ階層)へ配置してください。

sample/
├─ index.php
└─ users.csv

index.php が会員登録画面です。登録された会員情報は users.csv へ保存されます。

サーバーへ設置する場合は、index.php と users.csv を同じフォルダへアップロードしてください。

PHPはサーバー上で実行されるため、PHPファイルをダブルクリックしても動作しません。動作確認はレンタルサーバーへアップロードするか、PHPが利用できるローカル環境で行ってください。


コメント