如何为简报生成取消订阅链接?

时间:2013-06-17 08:05:36

标签: php subscription newsletter unsubscribe

我想用php写一份时事通讯。但我有一个问题:如何生成取消订阅的代码。实际上,我想为每个订户提供唯一的代码。例如,在“http://net.tutsplus.com/”中,您可以看到如下内容:“http://tutsplus.us1.list-manage.com/profile?u=0154weg635df2fdwied2541cbed&id=c5652sdfre7&e=8758563dfgde”。 另一个问题是这个代码应该保存在数据库中还是没有?(因为我认为如果它对每个人来说都是唯一的,那么每次发送新闻通讯都没有必要生成)。任何想法?

2 个答案:

答案 0 :(得分:18)

生成用户标识的哈希值+一些秘密字符串,将id和哈希值放入链接,并在验证哈希值后使用将取消订阅用户的脚本来提供它。

哈希不必在数据库中,只需动态计算即可。

创建取消订阅链接的脚本:

<?
$link = "unsubscribe.php?id=$user['id']&validation_hash=".md5($user['id'].$SECRET_STRING)
<a href="<?=$link?>">Unsubscribe</a>

处理取消订阅链接的脚本:

function unsubscribe() {

    $expected = md5( $user['id'] . $SECRET_STRING );

    if( $_GET['validation_hash'] != $expected )
        throw new Exception("Validation failed.");

    sql("UPDATE users SET wants_newsletter = FALSE WHERE id = " . escape($_GET['id']);
}

这不是最安全的东西,但足够好。

答案 1 :(得分:1)

是的,它应保存在数据库中。你应该使用像wamp,lamp或xampp这样的东西。这些是本地服务器,并为您提供了一个mysql数据库(phpmyadmin)。

要连接数据库,可以使用:

<?php
    define("DB_HOST", "localhost");/*host*/
    define("DB_USERNAME", "username");/*username*/
    define("DB_PASSWORD", "pass123");/*password*/
    define("DB_NAME", "mydatabase");/*database name*/

    try
    {
        $db_conn = new PDO('pgsql:host='.DB_HOST.';dbname='.DB_NAME,DB_USERNAME,DB_PASSWORD);
    }
    catch(PDOException $e)
    {
        print "Error!:".$e->getMessage()."\n";
        die();
    }
?>

然后,您可以尝试在mysql中创建一个新表:

CREATE TABLE subcribe
(
subscribeId     INT,
emailadress     VARCHAR(60),
....
);

然后,您可以像这样添加订阅者到您的数据库:

如果他登录,则为emailadress设置一个cookie:

setcookie('emailadress',$hisEmailadress,time()+3600);

然后添加subcriber:

  $emailadress=$_COOKIE['emailadress'];
    $subscriberId = $db_conn->prepare('SELECT MAX(subscriberId) FROM subcribe');
    $subscriberId ->execute();
    $row = $subscriberId ->fetch(PDO::FETCH_BOTH);
    $subscriberId = $row[0]+1;/*unique number because it's one higher then max*/    
    $subscriber = $db_conn->prepare("INSERT INTO subscribe(subscriberId, emailadress) VALUES('$subscriberId','$emailadress')");
    $subscriber ->execute();

取消订阅,只需这样做:

$unsubscribe = $db_conn->prepare('DELETE FROM subscribe WHERE emailadress=:emailadress');
$unsubscribe->bindParam(':emailadress',$_COOKIE['emailadress'],PDO::PARAM_STR);
$unsubscribe->execute();

要生成链接,您可以这样做并将其发送给电子邮件人员

$length = rand(5, 10);
$link= "";
for($i=0;$i< $length;$i++)/*create random link*/
{
   $char = rand(0, 256);

   if(($char>=65 && $char<=90) || ($char>=97 && $char<=122) || ($char>=48 && $char<=57))
   {
      $char = chr($char);
      $link.= $link;
   }
   else
    $i--;
}

$hash =  hash("ripemd160",$link);
setcookie('unsubscribe',$hash,time()+300);

$result = mail($emailadress, 'unsubscribe link', 'you are about to unsubscribe yourself. Click this link to unsubscribe: http://yourSite.php?link='.$link);

在此页面中,您可以使用该代码删除订阅者,如上所述。

PS:链接本身不应该添加到数据库,因为你可以设置一个有效时间的cookie(这里是5分钟)。 在此页面的页面中,您可以添加if-test以查看cookie是否已设置,然后删除订阅者。 if(isset($_COOKIE['unsubscribe'])){...}

希望它有所帮助;)