多邮箱mailto点击计数器异常:部分链接邮件主题为空
问题描述
我在页面上配置了多个邮箱地址,希望用户点击发送时对应计数递增。为此编写了counter.php实现计数逻辑,evaluation.php整合邮箱地址与计数功能:
- 调用
evaluation.php时,会生成存储当前调用次数的counter.txt,以及记录调用详情的counter.log; - 点击链接时应将最新计数传入邮件主题,但实际情况为:点击链接1时,邮件主题正常携带计数且
counter.log记录正常;点击链接2和3时,counter.log虽有记录,但邮件主题为空,无法定位原因。
相关代码
counter.php
<?php if(!isset($_SESSION['ip-sperre'])||$_SESSION['ip-sperre'] < time()- 30){ $_SESSION['ip-sperre'] = time(); @$incoming = $_GET['sendValue']; $filename = $incoming."_counter.txt"; if (file_exists($filename)) { $file = fopen($filename,"r+"); $zaehler = fgets($file,255); fclose($file); } else { $zaehler = 0; } $zaehler++; echo 'E-Mail ' . $zaehler; $file = fopen($filename,"w"); fwrite($file,$zaehler); fclose($file); $inhalt = date("Y-m-d H:i:s").' - '.$incoming.': '.$zaehler." "; $file2 = fopen("counter.log","a+"); fwrite($file2,$inhalt); fclose($file2); } else { // echo "Sperre aktiv"; } ?>
evaluation.php
<?php include 'counter.php'; ?> <!--E-Mail 1--> <a href="mailto:email1?subject=<?php echo $subject=$zaehler; ?>">Email recipient</a> <br> <!--E-Mail 2--> <a href="mailto:email2?subject=<?php echo $subject=$zaehler; ?>">Email recipient</a> <br> <!--E-Mail 3--> <a href="mailto:email3?subject=<?php echo $subject=$zaehler; ?>">Email recipient</a> <br> <!--jQuery--> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!--Counter--> <script> function count(e) { var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "counter.php?sendValue=" + e, true); xmlhttp.send(); } /*Reload*/ $('a').click(function() { location.reload(); }); </script>
结果说明
- 点击链接1:邮件主题已填充
- 点击链接2:邮件主题为空
问题原因与修复方案
核心问题
- 会话未初始化:
counter.php使用$_SESSION但未调用session_start(),导致会话逻辑失效,后续请求中$zaehler变量未定义,直接输出空值。 - 计数未区分邮箱:页面加载时执行
counter.php未传入对应邮箱标识,所有链接共用同一个未正确赋值的$zaehler。 - 点击事件逻辑错误:先触发
mailto再重载页面,当前点击的邮件主题使用旧计数,且未调用count()传递邮箱标识,无法更新对应计数。
修复步骤
1. 初始化会话(修改counter.php)
在文件开头添加会话初始化代码:
<?php session_start(); // 新增:初始化会话 $zaehler = 0; // 新增:初始化变量,避免未定义错误 if(!isset($_SESSION['ip-sperre'])||$_SESSION['ip-sperre'] < time()- 30){ // 原有逻辑... } else { // 新增:限制时间内返回已有计数 @$incoming = $_GET['sendValue']; $filename = $incoming."_counter.txt"; if (file_exists($filename)) { $file = fopen($filename,"r+"); $zaehler = fgets($file,255); fclose($file); echo 'E-Mail ' . $zaehler; } else { echo 'E-Mail 0'; } } ?>
2. 重构链接与点击逻辑(修改evaluation.php)
移除页面加载时的counter.php引入,通过异步请求获取对应邮箱的最新计数后再打开邮件链接:
<?php // 移除原有的 include 'counter.php'; ?> <!--E-Mail 1--> <a href="#" class="email-link" data-email="email1">Email recipient</a> <br> <!--E-Mail 2--> <a href="#" class="email-link" data-email="email2">Email recipient</a> <br> <!--E-Mail 3--> <a href="#" class="email-link" data-email="email3">Email recipient</a> <br> <!--jQuery--> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <!--Counter--> <script> function getCounter(email, callback) { var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "counter.php?sendValue=" + email, true); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var count = this.responseText.replace('E-Mail ', ''); callback(count); } }; xmlhttp.send(); } $('.email-link').click(function(e) { e.preventDefault(); var email = $(this).data('email'); getCounter(email, function(count) { window.location.href = `mailto:${email}?subject=${count}`; setTimeout(() => location.reload(), 500); }); }); </script>
修复后逻辑
- 点击邮箱链接时,先异步请求
counter.php获取对应邮箱的最新计数(同时完成递增); - 获取计数后打开
mailto链接,确保主题携带最新数值; - 会话初始化后IP限制逻辑正常工作,避免短时间重复计数;
- 每个邮箱对应独立的计数文件,互不干扰。
内容的提问来源于stack exchange,提问作者knefie
相关产品推荐
相关产品推荐

