اشتراک خبرنامه, قابلیت متداولی است که در وبسایت یا وبلاگ ها استفاده می شود.
در این آموزش php قصد داریم به شما نحوه ساخت اشتراک خبرنامه ایمیل با PHP و MySQL را نشان بدیم.
قابلیت اشتراک ایمیلی مهمترین بخش از ایمیل مارکتینگ است. بیشتر وبسایت ها یک گزینه اشتراک ایمیل را ارایه می دهند تا بازدیدکنندگان آپدیت ها روزانه یا هفتگی خبرنامه را از وبسایت دریافت کنند.
در اشتراک خبرنامه, بروزرسانی های وبسایت به ایمیل مشترکین ارسال می شود و قابلیت اشتراک ایمیلی به راحتی با PHP قابل پیاده سازی است.
در این مثال از اسکریپت ساخت اشتراک خبرنامه ایمیل با PHP و MySQL موارد زیر پیاده سازی می شود:
- ساخت یک فرم اشتراک (subscription) با HTML
- افزودن اطلاعات مشترکین به دیتابس با PHP و MySQL
- ارسال لینک فعالسازی به ایمیل
- تایید مشترکین با ایمیل
قبل از شروع ساخت اشتراک خبرنامه ایمیل با PHP و MySQL نگاهی به ساختار فایل ها بیاندازید.
/email_subscription_with_php
├── config.php
├── index.html
├── subscription.php
├── Subscriber.class.php
├── js/
│ └── jquery.min.js
└── css/
└── style.css
ساخت جدول دیتابیس
به منظور ذخیره اطلاعات مشترکین, نیاز به جدولی در دیتابیس داریم.
کد SQL زیر یک جدول subscribers
در دیتابیس MySQL ایجاد می کند.
1 2 3 4 5 6 7 8 9 10 11 |
CREATE TABLE `subscribers` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) COLLATE utf8_unicode_ci NOT NULL, `email` varchar(200) COLLATE utf8_unicode_ci NOT NULL, `verify_code` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL, `is_verified` tinyint(1) NOT NULL DEFAULT '0', `created` datetime NOT NULL, `modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `status` tinyint(1) NOT NULL DEFAULT '1', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; |
کلاس Subscriber
کلاس Subscriber
به ما در اتصال به دیتابیس و مدیریت عملیات مربوط به دیتابیس کمک می کند.
_construct()
– اتصال به دیتابیس MySQLgetRows()
– دریافت رکوردها از دیتابیسInsert()
– افزودن رکورد جدید به دیتابیسUpdate()
– بروزرسانی رکورد در دیتابیسDelete()
– حذف رکوردها از دیتابیس
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
<?php /* * Subscriber Class * This class is used for database related (connect, fetch, insert, update, and delete) operations * @author NetParadis.com * @url http://www.netparadis.com */ class Subscriber { private $dbHost = DB_HOST; private $dbUsername = DB_USERNAME; private $dbPassword = DB_PASSWORD; private $dbName = DB_NAME; private $userTbl = 'subscribers'; function __construct(){ if(!isset($this->db)){ // Connect to the database $conn = new mysqli($this->dbHost, $this->dbUsername, $this->dbPassword, $this->dbName); if($conn->connect_error){ die("Failed to connect with MySQL: " . $conn->connect_error); }else{ $this->db = $conn; } } } public function getRows($conditions = array()){ $sql = 'SELECT '; $sql .= array_key_exists("select",$conditions)?$conditions['select']:'*'; $sql .= ' FROM '.$this->userTbl; if(array_key_exists("where",$conditions)){ $sql .= ' WHERE '; $i = 0; foreach($conditions['where'] as $key => $value){ $pre = ($i > 0)?' AND ':''; $sql .= $pre.$key." = '".$value."'"; $i++; } } if(array_key_exists("order_by",$conditions)){ $sql .= ' ORDER BY '.$conditions['order_by']; }else{ $sql .= ' ORDER BY id DESC '; } if(array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){ $sql .= ' LIMIT '.$conditions['start'].','.$conditions['limit']; }elseif(!array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){ $sql .= ' LIMIT '.$conditions['limit']; } $result = $this->db->query($sql); if(array_key_exists("return_type",$conditions) && $conditions['return_type'] != 'all'){ switch($conditions['return_type']){ case 'count': $data = $result->num_rows; break; case 'single': $data = $result->fetch_assoc(); break; default: $data = ''; } }else{ if($result->num_rows > 0){ while($row = $result->fetch_assoc()){ $data[] = $row; } } } return !empty($data)?$data:false; } public function insert($data){ if(!empty($data) && is_array($data)){ $columns = ''; $values = ''; $i = 0; if(!array_key_exists('created',$data)){ $data['created'] = date("Y-m-d H:i:s"); } if(!array_key_exists('modified',$data)){ $data['modified'] = date("Y-m-d H:i:s"); } foreach($data as $key=>$val){ $pre = ($i > 0)?', ':''; $columns .= $pre.$key; $values .= $pre."'".$this->db->real_escape_string($val)."'"; $i++; } $query = "INSERT INTO ".$this->userTbl." (".$columns.") VALUES (".$values.")"; $insert = $this->db->query($query); return $insert?$this->db->insert_id:false; }else{ return false; } } public function update($data, $conditions){ if(!empty($data) && is_array($data)){ $colvalSet = ''; $whereSql = ''; $i = 0; if(!array_key_exists('modified',$data)){ $data['modified'] = date("Y-m-d H:i:s"); } foreach($data as $key=>$val){ $pre = ($i > 0)?', ':''; $colvalSet .= $pre.$key."='".$this->db->real_escape_string($val)."'"; $i++; } if(!empty($conditions)&& is_array($conditions)){ $whereSql .= ' WHERE '; $i = 0; foreach($conditions as $key => $value){ $pre = ($i > 0)?' AND ':''; $whereSql .= $pre.$key." = '".$value."'"; $i++; } } $query = "UPDATE ".$this->userTbl." SET ".$colvalSet.$whereSql; $update = $this->db->query($query); return $update?$this->db->affected_rows:false; }else{ return false; } } public function delete($conditions){ $whereSql = ''; if(!empty($conditions)&& is_array($conditions)){ $whereSql .= ' WHERE '; $i = 0; foreach($conditions as $key => $value){ $pre = ($i > 0)?' AND ':''; $whereSql .= $pre.$key." = '".$value."'"; $i++; } } $query = "DELETE FROM ".$this->userTbl.$whereSql; $delete = $this->db->query($query); return $delete?true:false; } } |
تنظیمات سایت و پیکربندی دیتابیس (config.php)
تنظیمات پایه سایت و متغیرهای پیکربندی دیتابیس در این فایل تعریف شدند.
$siteName
– نام سایت$siteEmail
– ایمیل ارسال کنندهDB_HOST
– هاست دیتابیس (پیش فرض : localhost)DB_USERNAME
– نام کاربری دیتابیسDB_PASSWORD
– رمزعبور دیتابیسDB_NAME
– نام دیتابیس
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php /* * Basic Site Settings and Database Configuration */ // Site Settings $siteName = 'Demo Site'; $siteEmail = 'sender@netpd.com'; $siteURL = ($_SERVER["HTTPS"] == "on")?'https://':'http://'; $siteURL = $siteURL.$_SERVER["SERVER_NAME"].dirname($_SERVER['REQUEST_URI']).'/'; // Database configuration define('DB_HOST', 'MySQL_Database_Host'); define('DB_USERNAME', 'MySQL_Database_Username'); define('DB_PASSWORD', 'MySQL_Database_Password'); define('DB_NAME', 'MySQL_Database_Name'); |
فرم اشتراک ایمیل
ما یک فرم HTML برای دریافت نام و ایمیل از بازدیدکننده را با کدهای زیر ساختیم
1 2 3 4 5 6 7 8 9 |
<!-- Display form submission status --> <div class="status"></div> <!-- Subscription form --> <form action="#" id="subsFrm" method="post"> <input type="text" id="name" placeholder="Full Name" required=""> <input type="email" id="email" placeholder="E-mail" required=""> <input type="button" id="subscribeBtn" value="Subscribe Now"> </form> |
سابمیت فرم اشتراک
فرم اشتراک بدون رفرش به سمت سرور ارسال می شود
در اینجا از Ajax برای پست کردن داده های فرم استفاده کردیم بنابراین اول کتابخانه jQuery را فراخوانی می کنیم.
1 |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> |
با سابمیت, داده های فرم با jQuery و Ajax ارسال می شوند.
- ورودی های نام و ایمیل توسط Regex در جی کوئری اعتبارسنجی می شوند.
- داده های فرم با متد
$.ajax()
به اسکریپت سمت سرور (php) ارسال می شوند.
بر اساس پاسخ برگشتی, وضعیت به کاربر نمایش داده می شود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
<script> $(document).ready(function(){ $('#subscribeBtn').on('click', function(){ // Remove previous status message $('.status').html(''); // Email and name regex var regEmail = /^[A-Z0-9._%+-]+@([A-Z0-9-]+\.)+[A-Z]{2,4}$/i; var regName = /^[a-zA-Z]+ [a-zA-Z]+$/; // Get input values var name = $('#name').val(); var email = $('#email').val(); // Validate input fields if(name.trim() == '' ){ alert('Please enter your name.'); $('#name').focus(); return false; }else if (!regName.test(name)){ alert('Please enter a valid name (first & last name).'); $('#name').focus(); return false; }else if(email.trim() == '' ){ alert('Please enter your email.'); $('#email').focus(); return false; }else if(email.trim() != '' && !regEmail.test(email)){ alert('Please enter a valid email.'); $('#email').focus(); return false; }else{ // Post subscription form via Ajax $.ajax({ type:'POST', url:'subscription.php', dataType: "json", data:{subscribe:1,name:name,email:email}, beforeSend: function () { $('#subscribeBtn').attr("disabled", "disabled"); $('.content-frm').css('opacity', '.5'); }, success:function(data){ if(data.status == 'ok'){ $('#subsFrm')[0].reset(); $('.status').html('<p class="success">'+data.msg+'</p>'); }else{ $('.status').html('<p class="error">'+data.msg+'</p>'); } $('#subscribeBtn').removeAttr("disabled"); $('.content-frm').css('opacity', ''); } }); } }); }); </script> |
افزودن اطلاعات مشترک به دیتابیس (subscription.php)
اگر درخواست اشتراک ایمیل (subscribe
) دریافت شد :
- داده ها از آرایه سراسری
$_POST
در PHP خوانده می شود. - بر روی ورودی های فلید فرم با اعتبارسنجی سمت سرور PHP انجام می شود.
- با تابع
getRows()
از کلاسSubscriber
بررسی می کند که ایمیل قبلا ثبت نشده باشد. - اطلاعات مشترک را با تابع
insert()
از کلاسSubscriber
در دیتابیس ذخیره می کند. - ایمیل تایید را با PHP ارسال می کند. (ارسال ایمیل با php)
- پاسخ را در فرمت کدشده jSON برگشت می دهد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
<?php // Include config file require_once 'config.php'; // Include Subscriber class require_once 'Subscriber.class.php'; $subscriber = new Subscriber(); if(isset($_POST['subscribe'])){ $errorMsg = ''; // Default response $response = array( 'status' => 'err', 'msg' => 'Something went wrong, please try after some time.' ); // Input fields validation if(empty($_POST['name'])){ $pre = !empty($msg)?'<br/>':''; $errorMsg .= $pre.'Please enter your full name.'; } if(empty($_POST['email']) && !filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)){ $pre = !empty($msg)?'<br/>':''; $errorMsg .= $pre.'Please enter a valid email.'; } // If validation successful if(empty($errorMsg)){ $name = $_POST['name']; $email = $_POST['email']; $verify_code = md5(uniqid(mt_rand())); // Check whether the given email already exists $con = array( 'where' => array( 'email' => $email ), 'return_type' => 'count' ); $prevRow = $subscriber->getRows($con); if($prevRow > 0){ $response['msg'] = 'Your email already exists in our subscribers list.'; }else{ // Insert subscriber info $data = array( 'name' => $name, 'email' => $email, 'verify_code' => $verify_code ); $insert = $subscriber->insert($data); if($insert){ // Verification email configuration $verifyLink = $siteURL.'subscription.php?email_verify='.$verify_code; $subject = 'Confirm Subscription'; $message = '<h1 style="font-size:22px;margin:18px 0 0;padding:0;text-align:left;color:#3c7bb6">Email Confirmation</h1> <p style="color:#616471;text-align:left;padding-top:15px;padding-right:40px;padding-bottom:30px;padding-left:40px;font-size:15px">Thank you for signing up with '.$siteName.'! Please confirm your email address by clicking the link below.</p> <p style="text-align:center;"> <a href="'.$verifyLink.'" style="border-radius:.25em;background-color:#4582e8;font-weight:400;min-width:180px;font-size:16px;line-height:100%;padding-top:18px;padding-right:30px;padding-bottom:18px;padding-left:30px;color:#fffffftext-decoration:none">Confirm Email</a> </p> <br><p><strong>'.$siteName.' Team</strong></p>'; $headers = "MIME-Version: 1.0" . "\r\n"; $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n"; $headers .= "From: $siteName"." <".$siteEmail.">"; // Send verification email $mail = mail($email, $subject, $message, $headers); if($mail){ $response = array( 'status' => 'ok', 'msg' => 'A verification link has been sent to your email address, please check your email and verify.' ); } } } }else{ $response['msg'] = $errorMsg; } // Return response echo json_encode($response); } ?> |
تایید ایمیل (subscription.php)
اگر درخواست تایید ایمیل (email_verify
) دریافت شد :
- با بررسی کد اعتبارسنجی, عملیات تایید مشترک را انجام می دهد.
- وضعیت اعتبارسنجی را با تابع
update()
از کلاسSubscriber
بروزرسانی می کند. - وضعیت اعتبارسنجی ایمیل را به کاربر نمایش می دهد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
<?php // Include config file require_once 'config.php'; // Include Subscriber class require_once 'Subscriber.class.php'; $subscriber = new Subscriber(); if(!empty($_GET['email_verify'])){ $verify_code = $_GET['email_verify']; $con = array( 'where' => array( 'verify_code' => $verify_code ), 'return_type' => 'count' ); $rowNum = $subscriber->getRows($con); if($rowNum > 0){ $data = array( 'is_verified' => 1 ); $con = array( 'verify_code' => $verify_code ); $update = $subscriber->update($data, $con); if($update){ $statusMsg = '<p class="success">Your email address has been verified successfully.</p>'; }else{ $statusMsg = '<p class="error">Some problem occurred on verifying your email, please try again.</p>'; } }else{ $statusMsg = '<p class="error">You have clicked on the wrong link, please check your email and try again.</p>'; } ?> <!DOCTYPE html> <html lang="en"> <head> <title>Email Verification by CodexWorld</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta charset="utf-8"> <!-- web-fonts --> <link href="//fonts.googleapis.com/css?family=Raleway:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&subset=latin-ext" rel="stylesheet"> <!-- Stylesheet file --> <link rel="stylesheet" type="text/css" href="css/style.css" /> </head> <body class="subs"> <div class="container"> <div class="subscribe box-sizing"> <div class="sloc-wrap box-sizing"> <div class="sloc-content"> <div class="sloc-text"> <div class="sloc-header"><?php echo $statusMsg; ?></div> </div> <a href="<?php echo $siteURL; ?>" class="cwlink">Go to Site</a> </div> </div> </div> </div> </body> </html> <?php } ?> |
جمع بندی
اسکریپت اشتراک ایمیلی به شما کمک می کند که به راحتی قابلیت اشتراک خبرنامه را به وبسایت یا پروژه خود اضافه کنید.
اشتراک ایمیل و قابلیت اعتبارسنجی بدون رفرش صفحه کار می کند و باعث می شود این فرایند کاربرپسند باشد.
شما به راحتی می توانید اسکریپت اشتراک خبرنامه ایمیل را بر اساس نیازهای پروژه خود توسعه بدید.
امیدوارم از آموزش ساخت اشتراک خبرنامه ایمیل با PHP و MySQL نهایت استفاده را برده باشید و در پروژه های خود از آن بهره ببرید.
هر سوالی داشتید ، از قسمت نظرات ارسال کنید . سریعا ، پاسخگوی سوالات شما هستیم .
موفق و پیروز باشید.
آقای مهدس تو ذخیره فرم مشکلی ندارم . تو زمان ارسال خبرنامه موندم ک جچوری وقتی اپدیت جدید میاد این فیلدها ک هر کودوم چند انتخابی هستن رو مطابقت بدم تا اگر درست بود اعلان ایمیل بشه ب کاربر
دستور sql باید از شرط های where و or استفاده کنید
ممنونم . یه مشکلی که الان هست کاربر مثلا در فرم خبرنامه انتخاب میکنه ک اگر پست منتشر شده در سایت برای شهر های یک و دو بود منو باخبر کن . بعد این انتخاب شهر فیلد اول فرم هست و فیلدهای بعدی بازم حالت چندانتخایی دارن .
در نتیجه وقتی فرمی توسط کاربر پر میشه دارای مثلا ۵ بخش هست ک هر بخش خودش چند اپشن داره . اینو چطوری باید براش شرط نوشت ؟ اگر ممکنه یک مثال با کد بدید ممنون میشم
برای هر فیلد که نیازه جداگانه باید تو جدول, ستون بسازید تا بشه همه بخش ها رو ذخیره کرد
سلام آموزش مثل همیشه عالی هست . یک سوال داشتم . ار اشتراک خبرنامه رو بخواهیم بر اساس کلمات خاص یا دسته بندی خاص فعال کنیم به صورتیکه کاربر در فرم چندین گزینه رو انتخاب کنه و هر موقع پستی در سایت با اون گزینه های انتخابی کاربر منتشر شد ایمیل براش ارسال بشه . یک راهنمایی میفرمایید ؟
سلام. ممنون
خوشحالیم که مفید واقع شده
برای هر مورد یه ستون در جدول خبرنامه میسازید و بعد بصورت select option یا چک باکس امکان انتخاب رو به کاربر میدید
سلام ، این اسکریپت در یک سایت واقعی هم کار میکن ؟
آخه من شنیدم که تابع mail در هاست واقعی کار نمیکنه
و ارسال ایمیل به تعداد زیاد چطوره؟
من الان یک ماهه تو یادگیری ارسال خبرنامه موندم و به هیچ نتیجه ای هم نرسیدم
لطفا یه راهنمایی برادرانه به من کنید 🙂
سلام. بله کار می کنه ولی خب برای تعداد زیاد مطمینا محدودیت دارید که یا باید از سایت هایی مثل https://mailerlite.com اشتراک بگیرید یا اینکه سرور smtp تهیه کنید
سلام، ممنون از آموزش تون، چرا فایل برای دانلود هم نگذاشتید؟
سلام. خوشحالیم که مفید واقع شده.
متاسفانه فایل zip از سرور حذف شده و فقط کدها در پست وجود دارند که باید هر کد رو طبق ساختاری که اول آموزش توضیح دادیم داخل فایل های مربوطه قرار بدید تا کد شما تکمیل بشه
سلام خسته نباشید
در قسمت آموزش شما در دو جا کد برای فایل subscription.php نوشتید، من یکم گیج شدم الان دقیقا کدوم رو باید بنویسم؛ الان من جفتشون رو توی فایل قرار دادم اصلا کار نمیکنه !!!!
سلام ممنون. شما باید شرط مربوط به تایید ایمیل را که داخل یک if هست را به کد قبلی اضافه کنید و هر دو محتوای فایل subscription هستند.
منظور از کار نکردن را باید دقیق بگید که چه اروری دریافت می کنید تا بتونیم راهنمایی کنیم
برای اپلود کردن وردپرس روی هاست باید تمام فایل هارو اپلود کنم ؟؟
بله. حتما تمامی فایل ها را آپلود کنید
سلام
چطوری فرم ارسال ایمیل متصل به دیتابیس درست کنم
سلام. همین آموزش دقیقا اون چیزی که می خواید هست.
اگه میشه لینکشو بفرستین ممنون میشم
منظور همین پستی که نظر دادید آموزشی هست که نیاز دارید
خیلی خوبه ولی کاشکی سورسش رو هم بزارین
سلام.
اگر طبق آموزش برید و ساختار رو هم رعایت کنید که بصورت تصویر قرار داده شده و تمامی کدها هم با نام فایل ها روی آن ها نوشته شده کنار هم بچینید سورس کامل بدست میاد که کمتر از ۱۰ دقیقه می تونید این کار رو انجام بدید.
موفق باشید.