【发布时间】:2016-02-15 12:10:57
【问题描述】:
我找到了一些答案,例如this good one(它使用两个文件,一个用于表单,另一个用于处理),还有一些使用外部资源(例如数据库或简单文件)的其他答案。
我正在寻找的是防止多次提交同一个表单,尤其是当表单和 php 代码在同一个文件中并且不使用外部文件时。
这是我尝试过的:
<?php //fone.php
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
if(isset($_SESSION['token']))
$_SESSION['prv_token']=$_SESSION['token'];
$_SESSION['token']=md5(uniqid());
?>
<html>
<head><meta charset="utf-8"><title>TEST</title></head>
<body>
<?php
if($_SERVER['REQUEST_METHOD']=='POST' && $_POST['token']==$_SESSION['prv_token']){
echo "<p>Form Submited</p>";
}
?>
<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF'])?>">
<input type="hidden" name="token" value="<?php echo $_SESSION['token'];?>">
Name : <input type="text" name="name"><br>
Age : <input type="text" name="age"><br>
<input type="submit" name="submit">
</form>
</body>
</htmL>
此解决方案适用于我,但如果我在其他文件中使用 $_SESSION['token'],代码会中断。
【问题讨论】:
-
那么.....你的问题是什么?
-
@Glubus 防止多次提交同一个表单,在表单和php代码在同一个文件的情况下......并且不使用外部文件
-
我给每个表单一个隐藏字段中的唯一 ID。成功处理后,我将其添加到会话中具有表单 id 键的列表中。很容易检查我是否已经处理过。
-
啊,你说的很对,手动操作不好玩。我有一个自动生成它的类。它包括一个时间戳和其他东西,它进入一个名为“formstate”的隐藏状态。每个表单都有这个字段,当它返回时,它会作为标准表单处理的一部分进行检查。它实际上是表单安全性的一部分(CSRF 等)。它是一个经过压缩的序列化 PHP 数组。
-
请记住,我不会记录所有唯一 ID。只是我处理过的那些。我在
contact和data change表单上使用它。 “搜索表单”或login form并不是真正的form,因为它们不会更改数据。他们改变了state。