как создать ссылку для отказа от подписки на информационный бюллетень?

Я хочу написать информационный бюллетень на php. но у меня вопрос: как сгенерировать код для отказа от подписки. На самом деле мне нужен уникальный код для каждого подписчика. например, в 'http://net.tutsplus.com/' вы можете увидеть что-то вроде этого: 'http://tutsplus.us1.list-manage.com/profile?u=0154weg635df2fdwied2541cbed&id=c5652sdfre7&e=8758563dfgde '. и еще вопрос: нужно ли сохранять этот код в базе данных или нет? (потому что я думаю, что если он уникален для каждого человека, нет необходимости генерировать каждый раз при отправке информационных бюллетеней). любая идея?


person Fatemeh Gharri    schedule 17.06.2013    source источник


Ответы (2)


Сгенерируйте хэш идентификатора пользователя + некоторую секретную строку, поместите идентификатор и хеш в ссылку и обработайте ее с помощью сценария, который отменит подписку пользователя после проверки хеша.

Хэш не обязательно должен быть в базе данных, просто вычисляйте его на лету.

Скрипт, создающий ссылку для отписки:

<?
$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']);
}

Это не самая безопасная вещь, но достаточно хорошая.

person Ondra Žižka    schedule 17.06.2013
comment
tnx для вашего ответа, вы имеете в виду, что хеш будет сохранен в db? - person Fatemeh Gharri; 17.06.2013
comment
но таким образом кажется, что каждый раз, когда рассылается информационный бюллетень, у нас идет большой процесс! ты не согласен со мной? - person Fatemeh Gharri; 17.06.2013
comment
Ха-ха, нет, не совсем. Вычисление хэша из нескольких букв занимает примерно наносекунду. Наверное, меньше. В несколько сотен раз меньше, чем запрос к базе данных. - person Ondra Žižka; 17.06.2013
comment
И если вас беспокоит производительность, я бы рекомендовал оставить PHP и использовать Java. - person Ondra Žižka; 17.06.2013
comment
tnx за ваше предложение! но запрос - это просто время отписки, не каждый день, а несколько сотен раз! какая у тебя идея? - person Fatemeh Gharri; 17.06.2013
comment
позвольте нам продолжить это обсуждение в чате - person Fatemeh Gharri; 17.06.2013
comment
Вам, вероятно, следует написать простой тест, чтобы увидеть, что работает медленнее - будь то запрос к БД или создание хэша md5. Я бы порекомендовал вам перестать заботиться о микрооптимизациях для начинающих и лучше следовать ограничению запросов к БД до минимального практического правила. - person Ondra Žižka; 17.06.2013

Да, это можно сохранить в базе данных. Вам следует использовать что-то вроде 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),
....
);

затем вы можете добавить подписчика в свою базу данных следующим образом:

если он входит в систему, вы устанавливаете cookie для адреса электронной почты:

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

затем добавьте подписчик:

  $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'])){...}

Надеюсь, это помогло;)

person breght    schedule 17.06.2013
comment
Плохое решение. Если пользователь забудет логин, он будет получать письма вечно. - person Ondra Žižka; 17.06.2013
comment
зачем вам использовать куки, чтобы отписаться от кого-то ?? вы верите, что все используют только одну систему для входа в электронную почту? - person Coder anonymous; 26.04.2018