I want to write a newsletter with php. but i have a question: how can i generate a code for unsubscribe. In fact i want a unique code for each subscriber. for example in 'http://net.tutsplus.com/' you can see something like this:'http://tutsplus.us1.list-manage.com/profile?u=0154weg635df2fdwied2541cbed&id=c5652sdfre7&e=8758563dfgde'. and another question is that this code should be saved in data base or no?(because i think if it's unique for each person, it's not necessary to generate every time whiling send newsletters). any idea?
2 Answers
Generate a hash of the user id + some secret string, put the id and the hash to the link, and serve it using a script which would unsubscribe the user, after verifying the hash.
The hash doesn't have to be in a database, just compute it on the fly.
Script creating the unsubscribe link:
<? $link = "unsubscribe.php?id=$user['id']&validation_hash=".md5($user['id'].$SECRET_STRING) <a href="<?=$link?>">Unsubscribe</a> Script processing the unsubscribe link:
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']); } It's not the most secure thing ever, but good enough.
7 Comments
Yes it should be saved in a database. You should use something like wamp, lamp or xampp. These are local servers and gives you a mysql database (phpmyadmin) to work in.
to connect with the database, you can use this:
<?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(); } ?> then, you can try to create a new table in mysql like this:
CREATE TABLE subcribe ( subscribeId INT, emailadress VARCHAR(60), .... ); then, you can add a subscriber to your database like this:
if he logs in, you set a cookie for is emailadress:
setcookie('emailadress',$hisEmailadress,time()+3600); then add 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(); to unsubscribe, just do this:
$unsubscribe = $db_conn->prepare('DELETE FROM subscribe WHERE emailadress=:emailadress'); $unsubscribe->bindParam(':emailadress',$_COOKIE['emailadress'],PDO::PARAM_STR); $unsubscribe->execute(); TO GENERATE A LINK, you can do it like this and send it to the persons emailadres:
$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); And in this page, you can use the code to delete the subscriber as mentioned above.
PS: the link itself shouldn't be add to the database because you can set a cookie which is valid for a certain amount of time (here this is 5 minutes). in the page this page you can then add an if-test to see if the cookie was set and then delete the subscriber. if(isset($_COOKIE['unsubscribe'])){...}
Hope it helped ;)