PHPでCSV編集フォームを作る方法【サンプルコード付き】

php

PHPでCSV編集フォームを作る方法

PHPとCSVを使って編集フォームを作る方法を紹介します。CSVファイルに保存されているデータを一覧表示し、編集ボタンからモーダルを開いて内容を更新できるサンプルです。入力チェックやエラーメッセージ表示にも対応しており、データベースを使わずにCSVだけで簡単な管理画面を作りたい場合に利用できます。

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

デモ

更新が完了しました。
名前 カテゴリー メールアドレス 操作

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

<?php

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

if (($fp = fopen('data.csv', 'r')) !== false) {

    while (($data = fgetcsv($fp)) !== false) {
        $rows[] = $data;
    }

    fclose($fp);

}

$edit_index = isset($_GET['id'])
    ? (int)$_GET['id']
    : -1;

if (
    $_SERVER['REQUEST_METHOD'] === 'POST' &&
    isset($rows[$edit_index])
) {

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

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

    if ($category === '') {
        $errors['category'] = 'カテゴリーを選択してください。';
    }

    if ($email === '') {
        $errors['email'] = 'メールアドレスを入力してください。';
    } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        $errors['email'] = 'メールアドレスの形式が正しくありません。';
    }

    if (empty($errors)) {

        $rows[$edit_index] = [
            $name,
            $category,
            $email
        ];

        $fp = fopen('data.csv', 'w');

        foreach ($rows as $row) {
            fputcsv($fp, $row);
        }

        fclose($fp);

            header('Location: index.php?success=1');
            exit;

    }

}

$current = isset($rows[$edit_index])
    ? $rows[$edit_index]
    : ['', '', ''];

?>

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>CSV編集フォーム</title>

<style>

body{
  font-family:sans-serif;
  margin:20px;
}

.table-wrap{
  border:1px solid #e5e7eb;
  border-radius:20px;
  overflow:hidden;
}

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

th{
  background:#f7f2e5;
}

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

.edit-link{
  display:inline-block;
  border:none;
  background:#2563eb;
  color:#fff;
  padding:8px 14px;
  border-radius:8px;
  text-decoration:none;
  font-weight:700;
}

.modal{
  display:none;
  position:fixed;
  inset:0;
  background:rgba(0,0,0,.45);
  z-index:9999;
  align-items:center;
  justify-content:center;
  padding:20px;
  box-sizing:border-box;
}

.modal.show{
  display:flex;
}

.modal-card{
  width:100%;
  max-width:520px;
  background:#fff;
  border-radius:20px;
  padding:24px;
  box-sizing:border-box;
}

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

.form-group{
  margin-bottom:16px;
}

label{
  display:block;
  margin-bottom:6px;
  font-weight:700;
}

input,
select{
  width:100%;
  padding:14px 16px;
  border:1px solid #d1d5db;
  border-radius:10px;
  font-size:16px;
  box-sizing:border-box;
}

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

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

.btn-area{
  display:flex;
  gap:10px;
  margin-top:20px;
}

.save-btn{
  flex:1;
  border:none;
  background:#ff6a00;
  color:#fff;
  padding:14px;
  border-radius:10px;
  font-size:16px;
  font-weight:700;
  cursor:pointer;
}

.close-link{
  flex:1;
  display:block;
  text-align:center;
  background:#64748b;
  color:#fff;
  padding:14px;
  border-radius:10px;
  font-size:16px;
  font-weight:700;
  text-decoration:none;
  box-sizing:border-box;
}

.success{
  margin-bottom:20px;
  padding:12px 16px;
  background:#ecfdf5;
  border:1px solid #86efac;
  border-radius:10px;
}

</style>

</head>
<body>

<?php if(isset($_GET['success'])): ?>
<div class="success" id="successMessage">
  更新が完了しました。
</div>
<?php endif; ?>

<div class="table-wrap">

<table>

  <tr>
    <th>名前</th>
    <th>カテゴリー</th>
    <th>メールアドレス</th>
    <th>操作</th>
  </tr>

  <?php foreach ($rows as $index => $row): ?>

  <tr>
    <td><?= htmlspecialchars($row[0] ?? '', ENT_QUOTES, 'UTF-8') ?></td>
    <td><?= htmlspecialchars($row[1] ?? '', ENT_QUOTES, 'UTF-8') ?></td>
    <td><?= htmlspecialchars($row[2] ?? '', ENT_QUOTES, 'UTF-8') ?></td>
    <td>
      <a href="?id=<?= $index ?>" class="edit-link">
        編集
      </a>
    </td>
  </tr>

  <?php endforeach; ?>

</table>

</div>

<div class="modal <?= isset($rows[$edit_index]) ? 'show' : '' ?>">

  <div class="modal-card">

    <div class="modal-title">
      データ編集
    </div>

    <form method="post" action="?id=<?= $edit_index ?>">

      <div class="form-group">
        <label>名前</label>
        <input
          type="text"
          name="name"
          value="<?= htmlspecialchars($current[0] ?? '', ENT_QUOTES, 'UTF-8') ?>"
          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="form-group">
        <label>カテゴリー</label>

        <select
          name="category"
          class="<?= isset($errors['category']) ? 'input-error' : '' ?>">
          <option value="営業" <?= ($current[1] ?? '') === '営業' ? 'selected' : '' ?>>営業</option>
          <option value="企画" <?= ($current[1] ?? '') === '企画' ? 'selected' : '' ?>>企画</option>
          <option value="開発" <?= ($current[1] ?? '') === '開発' ? 'selected' : '' ?>>開発</option>
          <option value="デザイン" <?= ($current[1] ?? '') === 'デザイン' ? 'selected' : '' ?>>デザイン</option>
        </select>

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

      <div class="form-group">
        <label>メールアドレス</label>
        <input
          type="email"
          name="email"
          value="<?= htmlspecialchars($current[2] ?? '', ENT_QUOTES, 'UTF-8') ?>"
          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="btn-area">

        <button type="submit" class="save-btn">
          更新
        </button>

        <a href="index.php" class="close-link">
          閉じる
        </a>

      </div>

    </form>

  </div>

</div>

<script>
setTimeout(function(){
  const message = document.getElementById('successMessage');

  if(message){
    message.style.display = 'none';
  }
}, 3000);
</script>

</body>
</html>
コードをコピーする場合 使用するコードのタブを選び、「このタブをコピー」をクリックすると、現在表示中のコードをコピーできます。
サンプル一式を取得する場合 HTML・CSSなどすべてのファイルが必要な場合は、「サンプル一式をダウンロード」をクリックしてください。

ファイル構成と設置方法

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

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

index.php がCSV編集フォーム本体です。data.csv に保存されているデータを一覧表示し、編集ボタンをクリックするとモーダルで編集画面を開き、内容を更新できます。

サーバーへ設置する場合は、上記ファイルを同じフォルダ(同じ階層)へアップロードしてください。別フォルダへ配置する場合は、コード内のCSVファイルパスを変更してください。

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


こちらもおすすめ


コメント