PHP脚本无法将用户输入写入JSON文件,求问题排查
问题分析与修复方案
咱们来一步步拆解你遇到的问题,核心是前端提交的数据没有和后端PHP正确通信,加上PHP代码本身的几个语法错误,导致无法写入JSON文件。
你代码里的关键问题
1. PHP代码执行时机完全错了
你把处理写入JSON的PHP代码放在了HTML的<head>标签里,这部分代码在页面加载时就会运行,而不是用户点击「Add」按钮时触发。此时$_POST里根本没有用户输入的数据,自然不会写入任何内容到JSON文件。
2. PHP变量和语法错误
- 你用
$jsonContents = file_get_contents('js/json.json');读取了JSON文件,但后面解码时却用了未定义的$json变量,应该是$jsonContents; - 最后写入文件时用的
$jsonString也没定义,你之前编码的变量是$json; - 添加数据时写了个错误的字符串格式数组:
array("'name':'.$name.', 'url':'.$url.'"),这不是合法的PHP关联数组,会导致JSON编码完全错误。
3. 表单提交逻辑只停留在前端
你的表单action设为javascript:void(0);,点击提交后只会执行JS的SSL.Add()方法,但这个方法只是把数据加到前端的Checker数组里,完全没有和后端PHP通信——服务器上的json.json文件根本不知道前端有新数据。
4. JS数据来源有问题
你直接使用Checker变量,但没有从json.json文件里加载初始数据,页面加载时这个数组是空的,也无法同步服务器端的已有数据。
修复方案
我们分三步来彻底解决这个问题:
第一步:单独创建PHP处理脚本(save-url.php)
把写入JSON的逻辑独立出来,这样可以通过AJAX在用户点击按钮时调用它:
<?php // 只允许POST请求 if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); echo json_encode(['status' => 'error', 'message' => '仅支持POST请求']); exit; } // 获取并验证用户输入 $name = trim($_POST['addname'] ?? ''); $url = trim($_POST['addlink'] ?? ''); if (empty($name) || empty($url)) { echo json_encode(['status' => 'error', 'message' => '名称和链接不能为空']); exit; } // 读取现有JSON数据 $jsonFile = 'js/json.json'; $data = []; if (file_exists($jsonFile)) { $jsonContents = file_get_contents($jsonFile); $data = json_decode($jsonContents, true) ?? []; } // 添加新数据(用合法的关联数组) $data[] = [ 'name' => $name, 'url' => $url ]; // 写入JSON文件 $json = json_encode($data, JSON_PRETTY_PRINT); if (file_put_contents($jsonFile, $json)) { echo json_encode(['status' => 'success', 'data' => ['name' => $name, 'url' => $url]]); } else { echo json_encode(['status' => 'error', 'message' => '写入文件失败,请检查目录权限']); } ?>
第二步:修改HTML代码
移除<head>里的PHP代码,修复表单和编辑框的结构:
<!DOCTYPE html> <html> <head> <title>SSL Checker</title> <link rel="stylesheet" type="text/css" href="css/style.css"> <script type="text/javascript" src="js/script.js"></script> </head> <body onLoad="start()"> <div id="title"> <h1>SSL Checker</h1> </div> <div id="data"> <form id="addForm" method="POST"> <input type="text" name="addname" id="add-name" placeholder="Name" required> <input type="text" name="addlink" id="add-link" placeholder="Link" required> <input type="submit" value="Add"> </form> <div id="edit" role="aria-hidden"> <form method="POST" id="saveEdit"> <input type="text" id="edit-name"> <input type="text" id="edit-link"> <!-- 补上之前缺失的链接编辑框 --> <input type="submit" value="Edit" /> <a onclick="CloseInput()" aria-label="Close">✖</a> </form> </div> <p id="counter"></p> </div> <div id="table"> <table style="overflow-x:auto;"> <tr> <th>Sites:</th> </tr> <tbody id="urls"></tbody> </table> </div> </body> </html>
第三步:修改JS代码
更新Add方法,通过AJAX提交数据到PHP脚本,同时修复初始数据加载逻辑:
function start() { // 初始化数据数组,从服务器加载现有数据 let Checker = []; fetch('js/json.json') .then(res => res.json()) .then(data => { Checker = data || []; SSL.FetchAll(); }) .catch(err => console.error('加载初始数据失败:', err)); var SSL = new function() { this.el = document.getElementById('urls'); this.Count = function(data) { const el = document.getElementById('counter'); const name = data > 1 ? 'urls' : 'url'; el.innerHTML = data ? `There are: ${data} ${name}` : `No ${name}`; }; this.FetchAll = function() { let data = ''; if (Checker.length > 0) { Checker.forEach((item, i) => { data += ` <tr> <td><a href="http://${item.url}" target="_blank">${item.name}</a></td> <td><button onclick="SSL.Edit(${i})">Edit</button></td> <td><button onclick="SSL.Delete(${i})">Delete</button></td> </tr> `; }); } this.Count(Checker.length); this.el.innerHTML = data; }; this.Add = function(e) { e.preventDefault(); // 阻止表单默认提交 const name = document.getElementById('add-name').value.trim(); const url = document.getElementById('add-link').value.trim(); if (name && url) { // 用AJAX提交数据到PHP脚本 fetch('save-url.php', { method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: `addname=${encodeURIComponent(name)}&addlink=${encodeURIComponent(url)}` }) .then(res => res.json()) .then(result => { if (result.status === 'success') { Checker.push(result.data); SSL.FetchAll(); // 清空输入框 document.getElementById('add-name').value = ''; document.getElementById('add-link').value = ''; } else { alert(result.message); } }) .catch(err => { console.error('保存数据失败:', err); alert('保存失败,请稍后重试'); }); } }; this.Edit = function(item) { const nameInput = document.getElementById('edit-name'); const urlInput = document.getElementById('edit-link'); nameInput.value = Checker[item].name; urlInput.value = Checker[item].url; document.getElementById('edit').style.display = 'block'; const self = this; document.getElementById('saveEdit').onsubmit = function(e) { e.preventDefault(); const name = nameInput.value.trim(); const url = urlInput.value.trim(); if (name && url) { Checker[item].name = name; Checker[item].url = url; self.FetchAll(); CloseInput(); // 这里可以添加AJAX请求同步更新服务器JSON文件,逻辑和Add类似 } }; }; this.Delete = function(item) { Checker.splice(item, 1); this.FetchAll(); // 同样可以添加AJAX请求删除服务器上对应数据 }; }; // 绑定表单提交事件 document.getElementById('addForm').addEventListener('submit', SSL.Add); window.SSL = SSL; } function CloseInput() { document.getElementById('edit').style.display = 'none'; } window.CloseInput = CloseInput;
额外注意事项
- 确保
js/目录有写入权限,否则PHP无法修改json.json文件; - 初始的
json.json文件内容应为空数组[],避免第一次读取时解析错误; - 编辑和删除功能的后端同步逻辑可以参考Add的AJAX写法,实现前后端数据一致。
内容的提问来源于stack exchange,提问作者Joanmi
相关产品推荐
相关产品推荐

