【问题标题】:Counter of submitted forms in phpphp中提交表单的计数器
【发布时间】:2019-12-29 21:15:40
【问题描述】:

我正在尝试在 php 中创建一个用于提交表单的计数器,如果表单中的数据发送到服务器 +1 is written to the counter.txt file,则此数据用于形成信中的标题。一切正常,但5 identical letters come to the mail, the next time it sends 10 and so on。问题是什么?为什么会这样? 当我删除计数器代码时,一切正常,一封信到达。

  <?php


$email = ($_POST['sel']);
$change = ($_POST['button-set']);
$name = ($_POST['name']);
$question = ($_POST['message']);
$submit = ($_POST['submit']); 

if (isset ($submit)) {
    $count = file_get_contents ('counter.txt');
    $count ++;
    file_put_contents ('counter.txt', $count);
}
else {
    $count = file_get_contents ('counter.txt');
};

$to = 'support@archsupport.ru'; 
$subject = 'Application number: ' . $count . 'from the site archsupport.ru';  
$message = 'Name: ' . $name . "\r\n" . 'Contacts: ' . $email . "\r\n" . 'Write ' . $change . "\r\n" . 'Question: ' . $question  ; 
$headers = 'From: zergg52@gmail.com ' . "\r\n";
$subject = preg_replace("/(\r\n)|(\r)|(\n)/", "", $subject);
$subject = preg_replace("/(\t)/", " ", $subject);
$subject = '=?UTF-8?B?' . base64_encode($subject) . '?=';
@mail($to, $subject, $message, $headers);
echo 'message sent!';
var_dump($email,$change,$name,$question,$submit,$count)
?>

页面代码:

var form = document.getElementsByTagName('form')[0];
var names = document.getElementById('name');
var validn = document.getElementById('vn');
var iconrequired = document.querySelector('#namereq');
var email = document.getElementById('sellection');
var valids = document.getElementById('vs');
var iconrequireds = document.querySelector('#sellectionreq');
var text = document.getElementById('qestions');
var validt = document.getElementById('vt');
var iconrequiredt = document.querySelector('#textreq');


document.addEventListener('input', function validation() {

  var x = document.forms["support"]["sellection"].value;


  if (names.validity.valid) {
    validn.className = "valid";
    iconrequired.className = "iconrequired hide";

  };

  if (email.validity.valid && x != "") {

    valids.className = "valid";
    iconrequireds.className = "iconrequired hide";

  };
  if (text.validity.valid) {
    validt.className = "valid";
    iconrequiredt.className = "iconrequired hide";

  };
  if (!names.validity.valid) {
    validn.className = "invalid";
    iconrequired.className = "iconrequired hide";

  };
  if (!email.validity.valid) {
    valids.className = "invalid";
    iconrequireds.className = "iconrequired hide";

  };

  if (!text.validity.valid) {
    validt.className = "invalid";
    iconrequiredt.className = "iconrequired hide";

  };

  if (names.validity.valid && email.validity.valid && text.validity.valid) {

    $('#support').submit(function() {

      $.post(
        'https://www.archsupport.ru/post-email.php',
        $("#support").serialize(),

        function(msg) {
          $('#support').hide('slow');
          $('#message').html(msg);
        }
      );


    });


  } else {

    return false;

  }
});





function validateSellection() {
  var x = document.forms["support"]["sellection"].value;
  if (x === "") {
    document.getElementById('sellectionreq').classList.remove("hide");
    return false;
  } else {
    document.getElementById('sellectionreq').classList.add("hide");
    return false;
  }
};

function validateName() {
  var x = document.forms["support"]["name"].value;
  if (x === "") {
    document.getElementById('namereq').classList.remove("hide");
    return false;
  } else {
    document.getElementById('namereq').classList.add("hide");
    return false;
  }
};

function validateText() {
  var x = document.forms["support"]["qestions"].value;
  if (x === "") {
    document.getElementById('textreq').classList.remove("hide");
    return false;
  } else {
    document.getElementById('textreq').classList.add("hide");
    return false;
  }
};

$('#support').submit(function validate() {
  if (validateName() && validateSellection() && validateText() === true) {

    return false;
  } else {

    validateSellection();
    validateName();
    validateText()
    return false

  }
});



$(".radio").on('click.two', function() {
  let input = $("#sellection");
  if ($("#radio").prop("checked")) {
    input.prop("disabled", false);
    input.prop({
      "type": "email",
      "placeholder": "example@yourmail.ru",
      "autocomplete": "email",
      "maxlength": "35",
      "minlength": "12",
      "value": "",
    });
    document.getElementById("sellection").pattern = "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$";
  } else {
    input.prop("disabled", false);
    $("#sellection").prop({
      "type": "tel",
      "placeholder": "+7-910-205-46-15",
      "autocomplete": "tel",
      "maxlength": "16",
      "minlength": "11",
      "value": "",
    });
    document.getElementById("sellection").pattern = "\\+7\\s?[\\(]{0,1}9[0-9]{2}[\\)]{0,1}\\s?\\d{3}[-]{0,1}\\d{2}[-]{0,1}\\d{2}";
  }
  input.focus();
  input.val("");
});

var fab = $('.icons');
fab.on('click.ten', function iconback() {
  fab.removeClass('checked');
  $(this).addClass('checked');
});
@keyframes req {
  0% {
    transform: translatex(0px);
  }
  100% {
    transform: translatex(5px);
  }
}

@keyframes inv {
  0% {
    opacity: .5;
  }
  100% {
    opacity: 1;
  }
}

* {
  padding: 0;
  margin: 0;
}

:root {
  font-family: "HelveticaNeueCyr";
  font-weight: 100;
}

form {
  font-size: 24px;
  position: relative;
  width: 100%;
  display: inline-flex;
  flex-direction: column;
}

textarea {
  height: 30vh;
  border-radius: 18px;
  padding-left: 15px;
  padding-top: 10px;
  border: 2px solid #d7d7d7;
  overflow: hidden;
  overflow-y: scroll;
  outline: none;
  resize: none
}

input,
textarea {
  font-family: "HelveticaNeueCyr";
  font-weight: 100;
  font-size: 18px;
}

 ::-webkit-input-placeholder {
  color: gray;
  font-size: 18px;
}

 ::-moz-placeholder {
  color: gray;
  font-size: 18px;
}


/* Firefox 19+ */

 :-moz-placeholder {
  color: gray;
  font-size: 18px;
}


/* Firefox 18- */

 :-ms-input-placeholder {
  color: gray;
  font-size: 18px;
}

input:not([type="submit"]) {
  border-radius: 100px;
  padding-left: 15px;
  height: 36px;
  border: none;
  background: #f3f3f3;
}

input:focus {
  outline: none;
  border: 2px solid #f3f3f3;
  box-sizing: border-box;
  background: white;
  padding-left: 13px;
}

.required {
  display: inline-flex;
  width: 100%;
  flex-direction: column;
  margin-bottom: 15px;
  position: relative;
}

.iconrequired {
  margin: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 90px;
  height: 14px;
  color: white;
  border-radius: 100px;
  font-size: 10px;
  font-weight: 100;
  font-family: "HelveticaNeueCyr";
  background: #343434;
  position: absolute;
  right: 15px;
  top: 10px;
  opacity: 1;
  transition: opacity ease-out 1s;
  animation: .05s ease-in-out 0s 4 alternate req;
}

input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
  transition: background-color 5000s ease-in-out 0s;
  border: 2px solid #f3f3f3;
  box-sizing: border-box;
  padding-left: 13px;
}

div.button-set {
  display: inline-flex;
}

div.button-set>label {
  position: relative;
  flex: 0 0 auto;
  height: 50px;
  width: 50px;
  margin-left: 15px;
  border-radius: 100px;
  outline: none;
  border: none;
  margin-bottom: 20px;
}

.checked {
  background: #f3f3f3;
  border-radius: 100px;
}

input[type="submit"] {
  font-family: "HelveticaNeueCyr";
  height: 36px;
  width: 160px;
  font-weight: 100;
  font-size: 24px;
  margin-top: 20px;
  margin-left: 10px;
  border: none;
  border-radius: 100px;
  background: #f3f3f3;
  padding: 0;
}

 ::-webkit-scrollbar {
  position: absolute;
  z-index: 9999;
  width: 5px;
}

 ::-webkit-scrollbar-button {
  display: none;
}

 ::-webkit-scrollbar-track {
  z-index: 9999;
  background-color: transparent;
}

 ::-webkit-scrollbar-track-piece {
  z-index: 9999;
  z-index: 9999;
  background-color: transparent;
}

 ::-webkit-scrollbar-thumb {
  z-index: 9999;
  background-color: #d7d7d7;
  border-radius: 3px;
}

 ::-webkit-scrollbar-corner {
  z-index: 9999;
  background-color: #d7d7d7;
}

.invalid {
  width: 12px;
  height: 12px;
  color: white;
  position: absolute;
  right: 15px;
  top: 12px;
  background: tomato;
  border-radius: 6px;
  animation: 2s ease-in-out 0s infinite alternate inv;
}

.valid {
  width: 12px;
  height: 12px;
  color: white;
  position: absolute;
  right: 15px;
  top: 12px;
  background: #9dc46b;
  border-radius: 6px;
  animation: 2s ease-in-out 0s infinite alternate inv;
}

.error {
  text-align: right;
  font-size: 12px;
  padding-right: 20px;
  padding-top: 10px;
  color: gray;
  letter-spacing: .05em;
}

.hide {
  display: none;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="/css/form.css">
</head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body>
  <form novalidate action="" method="post" name="support" id="support">
    <label class="required"><span id="vs" class="invalid hide"></span><input id="sellection" class="mail sellection" name="sel" vlaue="" placeholder="choose a communication way...."  required disabled><span id="error1"></span><div id="sellectionreq" class="iconrequired hide">REQUIRED</div></label>
    <div class="button-set">
      <label title="Email"><img class="icons" src='/img/icon/social_icon_mail_white.svg'><input class="radio" id="radio" type="radio" name="button-set" value="to mail" style="display:none;"></label>

      <label for="radio1" title="WhatsApp"><img class="icons" src='/img/icon/social_icon_whatsapp_white.svg'><input class="radio" id="radio1" type="radio" name="button-set" value="to WhatsApp" style="display:none;"></label>

      <label for="radio2" title="Telegram"><img class="icons" src='/img/icon/social_icon_telegram_white.svg'><input class="radio" id="radio2" type="radio" name="button-set" value="to Telegram" style="display:none;"></label>

      <label for="radio3" title="Viber"><img class="icons" src='/img/icon/social_icon_viber_white.svg'><input class="radio" id="radio3" type="radio" name="button-set" value="to Viber" style="display:none;"></label>
    </div>
    <label class="required"><span id="vn" class="invalid hide"></span>
			<input id="name" class="mail" type="name" name="name" autocomplete= none placeholder="what's your name...." value="" pattern="[A-Za-z]+(\s+[A-Za-z]+)?" maxlength="15" minlength="2" required><div id="namereq" class="iconrequired hide">REQUIRED</div></label>
    <label class="required"><span id="vt" class="invalid hide"></span><textarea id="qestions" type="text" placeholder="your question...." name="message" value="" pattern="[A-Za-z]+(\s+[A-Za-z]+)?" maxlength="400" minlength="4" required></textarea><div id="textreq" class="iconrequired hide">REQUIRED</div></label>
    <input name="submit" type="submit" id="submit" value="SUBMIT" />
  </form>
  <div id="message"></div>
</body>
<script src="/js/form.js"></script>

</html>

没有计数器:

var_dump($email,$change,$name,$question,$submit) - 字符串(12) "+79102054615" 字符串(11) "to WhatsApp" 字符串(4) "ZERG" 字符串(8) “任何东西”为空

带计数器:

var_dump($email,$change,$name,$question,$submit,$count) - 字符串 (12) "+79102054615" 字符串(11) "to WhatsApp" 字符串(4) "ZERG" 字符串(8) "ANYTHING" NULL 字符串(1) "9"

$count 立即取值为“9”

带有表单的站点:https://www.archsupport.ru/

【问题讨论】:

  • 当我在线运行您的脚本时,它会引发大量致命错误。这是因为这种奇怪的格式(不确定这是否与您在服务器上运行的代码相同,因为它不起作用)。只需写 '$var' 而不是 '$ var' 并且不要在 '$ _ POST' 等之间放置空格。在 else 之后,您可以删除分号。访问之前不需要先检查 $_POST['f'] 吗?我修复了它,至少我不再有错误了。 file_get_contents 将文件作为字符串返回 - 只有当内容是数字时,php 才会将其转换为 int(在 php 7 中测试)。你也应该使用数据库。
  • @F.Müller 是的,当然,格式有问题,我没有注意到服务器一切正常,问题不在于
  • 使用 var_dump() 来检查电子邮件参数,然后再在此处使用 @mail(...) 一次,而另一个则没有 - 尝试找出差异。从这个角度很难说。您可能想要更新您在此处发布的代码(其混乱且难以调试)。我需要查看调试输出才能找到错误。
  • @F.Müller 谢谢你,对我来说这一切都很困难,我是第一次做,所以我的代码太糟糕了
  • @F.Müller 根据您的要求更新,显然是 JS 中的情况

标签: javascript php jquery


【解决方案1】:

关于 HTML/JavaScript,请考虑以下代码。

$(function() {
  var form = $("#support");

  function checkFieldValidity(fObj) {
    var r = false;
    var re = new RegExp(fObj.attr("pattern"));
    var v = fObj.val();
    if (fObj.is("[required]")) {
      if (v.length) {
        fObj.next(".iconrequired").hide();
      } else {
        fObj.next(".iconrequired").show();
      }
      if (re.test(v)) {
        fObj.prev(".icon").removeClass("invalid").addClass("valid");
        r = true;
      } else {
        fObj.prev(".icon").removeClass("valid").addClass("invalid");
      }
    } else {
      r = true;
    }
    return r;
  }

  $("input", form).blur(function() {
    checkFieldValidity($(this));
  });

  form.submit(function(e) {
    e.preventDefault();
    var valid = true;
    $("[required]", form).each(function(i, el) {
      valid = valid && checkFieldValidity($(el));
    });
    return valid;
  });

  $(".button-set label", form).on('click', function() {
    $(this).parent().find(".checked").removeClass("checked");
    $("img", this).addClass("checked");
    var input = $("#sellection");
    input.prop("disabled", false);
    switch ($(this).data("value")) {
      case "email":
        input.prop({
          type: "email",
          placeholder: "example@yourmail.com",
          autocomplete: "email",
          maxlength: 35,
          minlength: 12,
          value: "",
        }).attr("pattern", "^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$");
        break;
        // Add Cases for each selection option if needed
      default:
        input.prop({
          "type": "tel",
          "placeholder": "+7-910-205-46-15",
          "autocomplete": "tel",
          "maxlength": "16",
          "minlength": "11",
          "value": "",
        });
        input.attr("pattern", "\\+7\\s?[\\(]{0,1}9[0-9]{2}[\\)]{0,1}\\s?\\d{3}[-]{0,1}\\d{2}[-]{0,1}\\d{2}");
        break;
    }
    input.focus();
    input.val("");
  });
});
@keyframes req {
  0% {
    transform: translatex(0px);
  }
  100% {
    transform: translatex(5px);
  }
}

@keyframes inv {
  0% {
    opacity: .5;
  }
  100% {
    opacity: 1;
  }
}

* {
  padding: 0;
  margin: 0;
}

:root {
  font-family: "HelveticaNeueCyr";
  font-weight: 100;
}

form {
  font-size: 24px;
  position: relative;
  width: 100%;
  display: inline-flex;
  flex-direction: column;
}

textarea {
  height: 30vh;
  border-radius: 18px;
  padding-left: 15px;
  padding-top: 10px;
  border: 2px solid #d7d7d7;
  overflow: hidden;
  overflow-y: scroll;
  outline: none;
  resize: none
}

input,
textarea {
  font-family: "HelveticaNeueCyr";
  font-weight: 100;
  font-size: 18px;
}

 ::-webkit-input-placeholder {
  color: gray;
  font-size: 18px;
}

 ::-moz-placeholder {
  color: gray;
  font-size: 18px;
}


/* Firefox 19+ */

 :-moz-placeholder {
  color: gray;
  font-size: 18px;
}


/* Firefox 18- */

 :-ms-input-placeholder {
  color: gray;
  font-size: 18px;
}

input:not([type="submit"]) {
  border-radius: 100px;
  padding-left: 15px;
  height: 36px;
  border: none;
  background: #f3f3f3;
}

input:focus {
  outline: none;
  border: 2px solid #f3f3f3;
  box-sizing: border-box;
  background: white;
  padding-left: 13px;
}

.required {
  display: inline-flex;
  width: 100%;
  flex-direction: column;
  margin-bottom: 15px;
  position: relative;
}

.iconrequired {
  margin: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 90px;
  height: 14px;
  color: white;
  border-radius: 100px;
  font-size: 10px;
  font-weight: 100;
  font-family: "HelveticaNeueCyr";
  background: #343434;
  position: absolute;
  right: 15px;
  top: 10px;
  opacity: 1;
  transition: opacity ease-out 1s;
  animation: .05s ease-in-out 0s 4 alternate req;
}

input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
  transition: background-color 5000s ease-in-out 0s;
  border: 2px solid #f3f3f3;
  box-sizing: border-box;
  padding-left: 13px;
}

div.button-set {
  display: inline-flex;
}

div.button-set>label {
  position: relative;
  flex: 0 0 auto;
  height: 50px;
  width: 50px;
  margin-left: 15px;
  border-radius: 100px;
  outline: none;
  border: none;
  margin-bottom: 20px;
}

.checked {
  background: #f3f3f3;
  border-radius: 100px;
}

input[type="submit"] {
  font-family: "HelveticaNeueCyr";
  height: 36px;
  width: 160px;
  font-weight: 100;
  font-size: 24px;
  margin-top: 20px;
  margin-left: 10px;
  border: none;
  border-radius: 100px;
  background: #f3f3f3;
  padding: 0;
}

 ::-webkit-scrollbar {
  position: absolute;
  z-index: 9999;
  width: 5px;
}

 ::-webkit-scrollbar-button {
  display: none;
}

 ::-webkit-scrollbar-track {
  z-index: 9999;
  background-color: transparent;
}

 ::-webkit-scrollbar-track-piece {
  z-index: 9999;
  z-index: 9999;
  background-color: transparent;
}

 ::-webkit-scrollbar-thumb {
  z-index: 9999;
  background-color: #d7d7d7;
  border-radius: 3px;
}

 ::-webkit-scrollbar-corner {
  z-index: 9999;
  background-color: #d7d7d7;
}

.invalid {
  width: 12px;
  height: 12px;
  color: white;
  position: absolute;
  right: 15px;
  top: 12px;
  background: tomato;
  border-radius: 6px;
  animation: 2s ease-in-out 0s infinite alternate inv;
}

.valid {
  width: 12px;
  height: 12px;
  color: white;
  position: absolute;
  right: 15px;
  top: 12px;
  background: #9dc46b;
  border-radius: 6px;
  animation: 2s ease-in-out 0s infinite alternate inv;
}

.error {
  text-align: right;
  font-size: 12px;
  padding-right: 20px;
  padding-top: 10px;
  color: gray;
  letter-spacing: .05em;
}

.hide {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form novalidate action="" method="post" name="support" id="support">
  <span class="icon"></span><input id="sellection" class="mail" name="f[sel]" value="" placeholder="Choose a communication method...." required disabled>
  <div class="iconrequired hide">REQUIRED</div>
  <div class="button-set">
    <label title="Email" data-value="email"><img class="icon" src='/img/icon/social_icon_mail_white.svg'></label>
    <label title="WhatsApp" data-value="whatsapp"><img class="icon" src='/img/icon/social_icon_whatsapp_white.svg'></label>
    <label title="Telegram" data-value="telegram"><img class="icon" src='/img/icon/social_icon_telegram_white.svg'></label>
    <label title="Viber" data-value="viber"><img class="icon" src='/img/icon/social_icon_viber_white.svg'></label>
  </div>
  <label class="required"><span class="icon"></span>
			<input id="name" class="mail" type="name" name="f[name]" autocomplete="none" placeholder="what's your name...." value="" pattern="[A-Za-z]+(\s+[A-Za-z]+)?" maxlength="15" minlength="2" required><div id="namereq" class="iconrequired hide">REQUIRED</div></label>
  <label class="required"><span id="vt" class="invalid hide"></span><textarea id="qestions" type="text" placeholder="your question...." name="f[message]" value="" pattern="[A-Za-z]+(\s+[A-Za-z]+)?" maxlength="400" minlength="45" required></textarea><div id="textreq" class="iconrequired hide">REQUIRED</div></label>
  <input name="f[submit]" type="submit" id="submit" value="SUBMIT" />
</form>
<div id="message"></div>

您想要评估所需的每个字段是否都有内容并与特定模式匹配。我认为你的方法太复杂了。此外,我会坚持使用所有原生 JavaScript 或所有 jQuery。不要混合它们。

对于submit,您需要测试每个字段并保持运行记录。为此,您可以从逻辑上以 true 值开始,并在测试时保持逻辑评估。示例:

var result = true;
result = result && true; // result is true
result = result && false; // result is false
result = result && true; // result is false

如果某些字段有效而任何无效,则结果将为false,并且不应提交表单。如果全部验证,结果将是true,并且可以安全地将数据提交给 PHP。这也应该防止多次提交。

请记住,这是客户端验证,可以通过手动将数据发布到 PHP 来绕过。大多数用户甚至都不会打扰,但只需要一个好奇或恶意的用户或机器人就可以看到他们可以绕过表单并创建自己的 HTTP Post Payload。因此,您需要确保您的 PHP 免受此类操作的影响。在您的 PHP 代码中使用之前测试用户提交的任何数据。例如,您这样定义$name:

$name = ($_POST['name']);

如果我构造一个像这样的有效载荷:

&name=;include "/etc/passwd";

这可能会在以下代码中进行评估:

$message = '姓名:' 。 $名称。 "\r\n" 。 '联系人:'。 $电子邮件。 "\r\n" 。 '写 ' 。 $改变。 "\r\n" 。 '问题: ' 。 $问题;

只是一些需要考虑的事情。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多