如何编写PHP双选择加入订阅表单

如何编写PHP双选择加入订阅表单,php,mysql,email,md5,Php,Mysql,Email,Md5,我正在尝试编写一个小PHP脚本,用于管理邮件列表的订阅。我试图在互联网上找到任何我能找到的资源,但我只想到: 非常简单的PHP脚本,只有单选择加入或“假”双选择加入功能 非常复杂的多MB PHP项目,如PHPList(7.8MB!) 使用“假”双选择加入I调用方法,该方法要么将电子邮件地址作为验证字符串,要么在浏览器中使用cookie 我只想做到: 有人可以在PHP表单中写入其电子邮件地址,然后单击提交 他收到一封带有URL的电子邮件,需要在其中单击。链接不应包含电子邮件地址,而应包含一些md5

我正在尝试编写一个小PHP脚本,用于管理邮件列表的订阅。我试图在互联网上找到任何我能找到的资源,但我只想到:

  • 非常简单的PHP脚本,只有单选择加入或“假”双选择加入功能
  • 非常复杂的多MB PHP项目,如PHPList(7.8MB!)
  • 使用“假”双选择加入I调用方法,该方法要么将电子邮件地址作为验证字符串,要么在浏览器中使用cookie

    我只想做到:

  • 有人可以在PHP表单中写入其电子邮件地址,然后单击提交
  • 他收到一封带有URL的电子邮件,需要在其中单击。链接不应包含电子邮件地址,而应包含一些md5或随机字符串
  • 单击URL后,他会进入一个显示“电子邮件已确认”的页面
  • 在服务器端,地址可以保存在受保护文件夹中的文本文件中,或者如果您认为将地址保存在数据库中非常重要,则可以保存在数据库中

    到目前为止,我的问题是:

  • 有人能给我介绍一些教程或写一篇关于如何写这样一个脚本的文章吗
  • 我应该使用数据库还是简单的文件。我所需要的只是插入简单的新电子邮件行,可能会重复检查
  • 如何存储双选择加入系统的临时id-s。我考虑使用类似于
    md5(“email”“passphrase”)
    的方法生成id,并将其存储在电子邮件地址旁边

  • 我建议使用
    md5(rand())
    生成一个随机字符串,并将其存储在数据库中。然后,为用户创建一个链接,并通过电子邮件发送给他。此链接应包含GET变量中的随机字符串,当加载确认页面时,可以将其与数据库进行比较

    如果字符串错误,则不执行任何操作并输出错误。如果正确,则从表中删除该行,并将其添加到另一个包含已确认电子邮件的表中(或者,在确认电子邮件后,设置一个名为
    的字段,并将其更改为
    TRUE


    您还应该有一个类似的方法,允许用户从邮件列表中取消订阅。

    为了好玩,这里有一个非常深入的示例。应该很容易理解那里发生了什么以及为什么

    警告:代码还没有经过测试,所以语法和其他错误是可能的

    <?php
    
    // Salt for hashing confirmation keys
    $salt = 'yoursecretstring12#11;.-_.21';
    
    $url = 'http://www.yoursite.tld/thisscript.php';
    $fromEmail = 'you@yoursite.tld';
    
    $dbHost = 'localhost';
    $dbUser = 'dbuser';
    $dbPass = 'dbpass';
    $dbDatabase = 'dbname';
    
    mysql_connect($dbHost, $dbUser, $dbPass);
    mysql_select_db($dbDatabase);
    
    $ip = $_SERVER["REMOTE_ADDR"];
    
    if ( isset( $_GET['key'] ) && isset( $_GET['email'] ) ) {
    
      // If we have 'email' and 'key' parameters, we are handling an opt-in click
    
      $email = mysql_real_escape_string( $_GET['email'] );
    
      // Check if key matches hash of email and salt combination and if email is really an email
    
      if ( sha1( $email.$salt ) == $_GET['key'] && filter_var($email, FILTER_VALIDATE_EMAIL) ) {
    
        // Check if entry already exists
    
        $checkDupes = mysql_query( "SELECT COUNT(*) as cnt FROM emails WHERE email = '$email'"; ); 
        $result = mysql_fetch_assoc($checkDupes);
    
        if ($result['cnt'] < 1) {
    
          // Fresh email, insert into db along with remote ip and timestamp
    
          mysql_query( "INSERT INTO emails (email, ip, timestamp) VALUES ( '$email', $ip, NOW() );" );
          die('Subscription confirmed!');
    
        } else {
    
          die('Email already exists in database');
    
        }
    
      } else {
    
        die('Key mismatch or invalid email!');  
    
      } 
    
    } else if ( isset( $_POST['email'] ) && filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) ) {
    
      // Form submission, send confirmation email    
    
      $email = $_POST['email'];
      $key = sha1( $email.$salt );
    
      $link = $url . '?email=' . $email . '&key=' . $key;
    
      $mailSubject = 'Please confirm your subscription';
      $mailTo = $email;
      $mailBody = 'Please confirm your subscription by clicking <a href="$link">this link</a>'; 
      $headers = 'From: ' . $fromEmail . "\r\n";
    
      mail( $mailTo, $mailSubject, $mailBody );
    
    } else {
    
      // Present form and show error if needed
    
      if ( isset( $_POST['email'] ) ) {
        echo "Ivalid email submitted!<br />";
      } 
    
      echo '
      <form method="post" action="'.$url.'">
        Email: <input type="text" name="email" /><br />
        <input type="submit" value="Submit" />
      </form>
      ';
    
    }
    

    不错,不过我想我可能会用类似这样的东西增强令牌,并将其与电子邮件一起存储<代码>$token=md5(str_shuffle(chr(mt_rand(32226)).uniqid().microtime(TRUE))
    然后在$\u GET请求中不通过网络传递电子邮件。取而代之的是,只需通过令牌查找电子邮件;错误,并且未传递标题。此外,单击“提交”后还有一个空页面。这是我的代码:另外,很难弄清楚如何创建SQL表。我最终得到了一份工作。请告诉我是否应该修改它。@zsero对这些错误感到抱歉,他们偷看了:)至于数据库,将ip和电子邮件的类型更改为VARCHAR(XX),其余的看起来可以。