PHP与jQuery实现CSV文件展示、新增及删除功能技术问询
解决方案:PHP + AJAX 实现CSV表格的增删功能
CSV更新方案选择结论
小数据量下优先选整体重写CSV,逻辑简单不易出错;大数据量(上千行级)再考虑单行处理。你的场景是逐行渲染表格,大概率数据规模不大,整体重写能避免单行追加时的格式混乱、删除时的行定位偏差等问题,可靠性更高。
功能实现步骤
一、前端HTML/JS(含表格渲染)
假设CSV有「姓名、邮箱、电话」三列,调整页面结构如下:
<!-- 核心表格 --> <table id="csvTable"> <thead> <tr> <th>姓名</th> <th>邮箱</th> <th>电话</th> <th>操作</th> </tr> </thead> <tbody> <!-- PHP渲染已有数据行 --> <?php $csvFile = 'data.csv'; if (($handle = fopen($csvFile, 'r')) !== FALSE) { while (($data = fgetcsv($handle, 1000, ',')) !== FALSE) { echo "<tr>"; echo "<td>" . htmlspecialchars($data[0]) . "</td>"; echo "<td>" . htmlspecialchars($data[1]) . "</td>"; echo "<td>" . htmlspecialchars($data[2]) . "</td>"; echo "<td><button class='deleteBtn' data-row='" . htmlspecialchars(implode(',', $data)) . "'>删除</button></td>"; echo "</tr>"; } fclose($handle); } ?> </tbody> </table> <!-- 新增行输入区 --> <div id="addRowArea"> <input type="text" id="inputName" placeholder="姓名"> <input type="email" id="inputEmail" placeholder="邮箱"> <input type="text" id="inputPhone" placeholder="电话"> <button id="saveNewRow">保存</button> </div> <script> // 新增行逻辑 document.getElementById('saveNewRow').addEventListener('click', function() { const name = document.getElementById('inputName').value.trim(); const email = document.getElementById('inputEmail').value.trim(); const phone = document.getElementById('inputPhone').value.trim(); if (!name || !email || !phone) { alert('请填写完整信息'); return; } // 发送AJAX请求 fetch('csv_handler.php', { method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: `action=add&name=${encodeURIComponent(name)}&email=${encodeURIComponent(email)}&phone=${encodeURIComponent(phone)}` }) .then(res => res.text()) .then(result => { if (result === 'success') { // 前端插入新行 const tbody = document.getElementById('csvTable').querySelector('tbody'); const newRow = document.createElement('tr'); newRow.innerHTML = ` <td>${htmlEscape(name)}</td> <td>${htmlEscape(email)}</td> <td>${htmlEscape(phone)}</td> <td><button class='deleteBtn' data-row='${encodeURIComponent(`${name},${email},${phone}`)}'>删除</button></td> `; tbody.appendChild(newRow); // 清空输入框 document.getElementById('inputName').value = ''; document.getElementById('inputEmail').value = ''; document.getElementById('inputPhone').value = ''; } else { alert('保存失败,请重试'); } }) .catch(err => console.error('请求出错:', err)); }); // 删除行逻辑 document.querySelectorAll('.deleteBtn').forEach(btn => { btn.addEventListener('click', function() { const rowData = decodeURIComponent(this.getAttribute('data-row')).split(','); const name = rowData[0]; const email = rowData[1]; const phone = rowData[2]; if (confirm('确定删除该行?')) { fetch('csv_handler.php', { method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: `action=delete&name=${encodeURIComponent(name)}&email=${encodeURIComponent(email)}&phone=${encodeURIComponent(phone)}` }) .then(res => res.text()) .then(result => { if (result === 'success') { // 前端移除该行 this.parentElement.parentElement.remove(); } else { alert('删除失败,请重试'); } }) .catch(err => console.error('请求出错:', err)); } }); }); // HTML字符转义辅助函数 function htmlEscape(str) { return str.replace(/[&<>"']/g, match => { const escapeMap = {'&':'&','<':'<','>':'>','"':'"',"'":'''}; return escapeMap[match]; }); } </script>
二、后端处理脚本(csv_handler.php)
负责接收AJAX请求,用整体重写方式更新CSV:
<?php $csvPath = 'data.csv'; // 初始化CSV(无文件则创建表头) if (!file_exists($csvPath)) { $header = ['姓名', '邮箱', '电话']; $handle = fopen($csvPath, 'w'); fputcsv($handle, $header); fclose($handle); } // 读取现有CSV数据到数组 $csvContent = []; if (($handle = fopen($csvPath, 'r')) !== FALSE) { while (($row = fgetcsv($handle, 1000, ',')) !== FALSE) { $csvContent[] = $row; } fclose($handle); } $action = $_POST['action'] ?? ''; switch ($action) { case 'add': $newRow = [ $_POST['name'] ?? '', $_POST['email'] ?? '', $_POST['phone'] ?? '' ]; // 过滤空行 if (!empty(array_filter($newRow))) { $csvContent[] = $newRow; // 重写CSV $handle = fopen($csvPath, 'w'); foreach ($csvContent as $row) fputcsv($handle, $row); fclose($handle); echo 'success'; } else echo 'error'; break; case 'delete': $targetRow = [ $_POST['name'] ?? '', $_POST['email'] ?? '', $_POST['phone'] ?? '' ]; // 过滤掉目标行 $updatedContent = array_filter($csvContent, fn($row) => $row !== $targetRow); // 重写CSV $handle = fopen($csvPath, 'w'); foreach ($updatedContent as $row) fputcsv($handle, $row); fclose($handle); echo 'success'; break; default: echo 'invalid_action'; break; } ?>
关键注意事项
- 权限配置:确保PHP对CSV文件有读写权限(可设置
chmod 644或755,依服务器环境调整)。 - 数据校验:实际使用时需增强输入校验(比如邮箱格式、电话格式),防止恶意输入破坏CSV结构。
- 并发安全:多用户操作场景下,需在读写文件时加锁,比如在
fopen后调用flock($handle, LOCK_EX),操作完成后调用flock($handle, LOCK_UN)。
内容的提问来源于stack exchange,提问作者T. Pluess
相关产品推荐
相关产品推荐

