PHPでCSVを使ったパスワード変更機能を作る方法【サンプルコード付き】

php

PHPでCSVを使ったパスワード変更機能を作る方法

PHPでCSVを使ったパスワード変更機能を作る方法を紹介します。ログイン中の会員が現在のパスワードを確認し、新しいパスワードへ変更できるサンプルです。データベースを使わずにCSVで会員情報を管理したい場合や、会員登録機能・ログイン機能へパスワード変更機能を追加したい場合に利用できます。

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

デモ

パスワード変更フォーム
サンプル現在パスワード:password123

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

<?php
session_start();

$csv_file = __DIR__ . '/users.csv';

function read_users($csv_file){

    $users = [];

    if (!file_exists($csv_file)) {
        return $users;
    }

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

    if (!$fp) {
        return $users;
    }

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

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

        $users[] = [
            $row[0] ?? '',
            $row[1] ?? '',
            $row[2] ?? '',
            $row[3] ?? ''
        ];

    }

    fclose($fp);

    return $users;

}

function save_users($csv_file, $users){

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

    if (!$fp) {
        die('users.csvに書き込めません。');
    }

    fputcsv($fp, [
        'id',
        'name',
        'email',
        'password'
    ]);

    foreach ($users as $user) {
        fputcsv($fp, $user);
    }

    fclose($fp);

}

$users = read_users($csv_file);

$message = '';
$errors = [];
$display_current_password = '';

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

    $current_password = $_POST['current_password'] ?? '';
    $new_password = $_POST['new_password'] ?? '';
    $confirm_password = $_POST['confirm_password'] ?? '';

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

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

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

    if ($new_password !== '' && strlen($new_password) < 8) {
        $errors[] = 'パスワードは8文字以上で入力してください。';
    }

    if ($new_password !== $confirm_password) {
        $errors[] = '新しいパスワードが一致しません。';
    }

    foreach ($users as $user) {

        if (
            $user[2] === 'test@example.com' &&
            password_verify($current_password, $user[3])
        ) {
            $display_current_password = $current_password;
            break;
        }

    }

    if (empty($errors)) {


        foreach ($users as $index => $user) {

            $password_ok = (
                $user[2] === 'test@example.com' &&
                password_verify($current_password, $user[3])
            );

            if ($password_ok) {

                $users[$index][3] = password_hash($new_password, PASSWORD_DEFAULT);

                save_users($csv_file, $users);

                $message = 'パスワードを変更しました。';
                $display_current_password = '';
                $current_password = '';
                $new_password = '';
                $confirm_password = '';

                break;

            }

        }

        if ($message === '') {

            $password_matched = false;

            foreach ($users as $user) {

                if (
                    $user[2] === 'test@example.com' &&
                    password_verify($current_password, $user[3])
                ) {
                    $password_matched = true;
                    break;
                }

            }

            if (!$password_matched) {
                $display_current_password = '';
                $errors[] = '現在のパスワードが正しくありません。';
            }

        }

    }

}

?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>パスワード変更機能</title>

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

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

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

.password-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;
}

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

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

.success{
  color:#15803d;
  font-size:14px;
  font-weight:700;
  padding:14px;
  border-radius:12px;
  border:1px solid #bbf7d0;
  background:#f0fdf4;
  margin-bottom:14px;
}

.sample{
  margin-top:16px;
  line-height:1.8;
  font-size:14px;
}
</style>
</head>
<body>

<div class="password-wrap">

  <div class="password-card">

    <div class="password-title">
      パスワード変更フォーム
    </div>

    <?php if ($message !== ''): ?>
      <div class="success">
        <?= htmlspecialchars($message, ENT_QUOTES, 'UTF-8') ?>
      </div>
    <?php endif; ?>

    <?php foreach ($errors as $error): ?>
      <div class="error">
        <?= htmlspecialchars($error, ENT_QUOTES, 'UTF-8') ?>
      </div>
    <?php endforeach; ?>

    <form method="post">

      <div class="field">
        <label>現在のパスワード</label>
        <input
          type="password"
          name="current_password"
          value="<?= htmlspecialchars($display_current_password, ENT_QUOTES, 'UTF-8') ?>"
          autocomplete="current-password">
      </div>

      <div class="field">
        <label>新しいパスワード</label>
        <input
          type="password"
          name="new_password"
          autocomplete="new-password">
      </div>

      <div class="field">
        <label>新しいパスワード(確認)</label>
        <input
          type="password"
          name="confirm_password"
          autocomplete="new-password">
      </div>

      <button
        type="submit"
        class="btn">
        パスワードを変更する
      </button>

    </form>

    <div class="sample">
      サンプル現在パスワード:password123
    </div>

  </div>

</div>

</body>
</html>

ファイル構成と設置方法

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

password-change/
├─ index.php
└─ users.csv

index.php がパスワード変更フォーム本体です。
users.csv に保存されている会員情報を読み込み、現在のパスワード確認後に新しいパスワードへ変更します。

パスワードは password_hash() でハッシュ化して保存されます。CSVへ平文パスワードを保存しないため、比較的安全に会員情報を管理できます。

サーバーへ設置する場合は、上記ファイルを同じフォルダ(同じ階層)へアップロードしてください。別フォルダへ配置する場合は、コード内の設定変更が必要になる場合があります。

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


コメント