I am facing a problem with sending bulk emails to all my recipients (approx 10,000) It sends about 600 - 800 mails and then just stops without any reason. I am using a shared server.
Here is My Code.
<?php
#session_start();
if(!isset($_SESSION['uid'])){
echo "<html><head>";
echo "<script language=javascript>function load25(){
alert('........................You Must Login .........................');
window.location='email_login.html';}</script>";
echo "</head><body onload=load25()></body></html>";
die();
}
include "connection.php";
$uid=$_SESSION['uid'];
//var_dump($uid);
require_once('mail.message.php');
require_once('mail.info.php');
$email_id=uniqid();
$m="<html><body>";
$m.= $_POST['content'];
$subject= $_POST['subject'];
$m.="<img src='http://emailpro.in/mail/trackerimage.php?utm_source=gmail&utm_medium=email&utm_content=image&utm_campaign=services&campaignID=1&subscriberID=".$email_id."&subject=".$subject."' border='0' alt='' style='height:1px;width:1px' />";
$to1=$_POST['to'];
$username=$_POST['usid'];
$passwd=$_POST['ppwd'];
$replymailid=$_POST['repmid'];
$campname=$_POST['campname'];
//echo" $replymailid <BR> $campname";
$timezone = new DateTimeZone("Asia/Kolkata" );
$date = new DateTime();
$date->setTimezone($timezone );
$date1= $date->format( 'y/m/d H:i:s');
//echo $date1;
//$datetimee= date('y/m/d - H:i:s') ;
//date('l jS \of F Y h:i:s A');
//echo "Time Is $date ";
function nowhitespace($data)
{
return preg_replace('/\s/', '',$data);
}
$to2=nowhitespace($to1);
$b=rtrim($to2,',');
//Print_r($b);
$s=array();
$s=explode(",","$b");
$n=$_POST['no'];
//echo "The number of emails u have selected is $n<br />";
$s=array();
$s=explode(",","$b");
$s1=implode(",", $s);
$Email = new Email();
$Email->sender = $replymailid;
$Email->recipient=$s1;
$Email->subject =$subject;
$Email->message_text = "Hello!";
$Email->message_html = $m;
// send the email
$Courier = new Courier();
$sent = $Courier->send($Email);
$result=mysql_query("INSERT INTO sentmails VALUES('','$uid','$campname','$subject','$b','$n','$date1')");
/*if(isset($_POST['no'])!=" ")*/
if($n!="")
{
$rec = mysql_query("SELECT * from clientmailid where userid='$uid' limit $n");
$count = mysql_num_rows($rec);
// echo $count;
if($n!=0 && $count!=0 && $n<=$count)
{
// echo $n;
$recipients = mysql_query("SELECT * from clientmailid where userid='$uid' limit $n");
while($row = mysql_fetch_array($recipients))
{
$addresses[]= $row['emailid'];
//echo $addresses;
}
$to = implode(",", $addresses);
// print_r($to);
/* $Tos=array();
$Tos=explode(",","$to");
$Tos1=implode(",", $Tos);
*/ $Email->recipient=$to;
} else
{
echo '<html>';
echo '<head></head>';
echo '<body onload=load30()>';
echo '</body>';
echo'</html>';
echo "**Sorry You Don't have enough Email Credits**";
}
}
if ($sent != Courier::SEND_OK) {
echo "Mailer Error" ;
}
else {
if($n!=0 && $count!=0){
$n=$_POST['no'];
$recipients = mysql_query("SELECT * from clientmailid where userid='$uid' limit $n");
while($row = mysql_fetch_array($recipients))
{
$addresses[]= $row['emailid'];
$mid=$row['mid'];
$result13 = mysql_query("delete FROM clientmailid where mid='$mid' limit $n");
//echo $addresses;
}
}
echo"<script>alert('Thank u for using emailpro Your mails will be processed and will be sent shortly');</script>";
echo '<script> window.location="./dashboard.php";</script>';
}
?>
<script type="text/javascript">
function load30()
{
alert("Sorry u don't have enough email credits");
window.location='./tofill.php';
}
</script>
I know that we can send send unlimited mails through a shared server and I am sure there is something wrong either with my code or something with the server. Please guide me accordingly....
Thanks
I don't think there is anything wrong with your code, not because I can read it (please put clearer code on SO) but that it sends a random amount between 600-800 successfully. The following problems are most likely and one of them or both will solve the problem:
1) One of the potential reasons can be PHP timing out the script. Every script gets to run for a limited amount of time. If your script takes more time than that then PHP will simply kill the script. Typically that should cause an error being reported in the error logs. Check your apache error log messages - they might contain a hint.
Just add ini_set('max_execution_time', 0); in the top of your mailing script to test if this is the problem.
2) Could this be being caused by your local mail server? If you're sending out 10.000 emails in a short space of time, it might be assuming that it's spamming, and stop once you reach a certain amount. Try creating a mailing queue and sending in periodically.
Related
I have a PHP script which opens an email inbox, searches for the last email and then performs some other operations if this email has the UNSEEN header.
The script is run by a cron job, and it works fine. The problem is that sometimes it takes several attempts before actually finding the new email, even if the email has already arrived.
If someone sees i'm missing something, or knows how to ensure i get all emails on the first try, please let me know. This is the relevant email opening and searching code code:
//open mailbox
$inbox = imap_open('{<domain>/imap/ssl/novalidate-cert}INBOX', '<email-address>', '<password>');
$newEmails = false;
// grab a list of all the mail headers
$msgnos = imap_search($inbox, 'ALL');
$headers = imap_headers($inbox);
$last = imap_num_msg($inbox);
//check if the last email is marked as unread (U means unread)
$headerinfo = imap_headerinfo($inbox, $last);
if($headerinfo->Unseen == 'U') {
$newEmails = true;
file_put_contents("program_logs.txt","[".date('d-m-Y H:i') . "] program executed. New mails found. \r\n",FILE_APPEND);
}
echo $headerinfo->Unseen . "<br>";
//read email if the last email is unread
if($newEmails == true){
$header = imap_header($inbox, $last);
$body = imap_fetchbody($inbox, $last,1);
$structure = imap_fetchstructure($inbox, $last);
$boxname = $header->from[0]->mailbox;
$hostname = $header->from[0]->host;
$title = $header->subject;
$from = $boxname."#".$hostname;
echo "<h2>Body structure Encoding:</h2>";
var_dump($structure->encoding);
echo "<hr>";
if($structure->encoding == 3){
$body = base64_decode($body);
}
if($structure->encoding == 4){
$body=quoted_printable_decode($body);
}
echo "<h2>Is body html?</h2>";
if($body != strip_tags($body)){
echo "body is html.<br>";
$body = preg_replace( "/\n\s+/", "\n", rtrim(html_entity_decode(strip_tags($body))) );
echo "converted to plain text.";
}else{
echo "body is not html";
}
echo "<hr>";
echo "<h2>From:</h2>".$from;
echo "<hr>";
echo "<h2>Body:</h2>".$body;
echo "<hr>";
echo "<h2>title:</h2>".$title;
echo "<hr>";
file_put_contents("program_logs.txt","Email is from ".$from. " \r\n",FILE_APPEND);
}else{
echo 'No new notifications';
echo "<hr>";
echo "<h2>imap erros:</h2>";
var_dump(imap_errors());
imap_close($inbox);
echo '<hr>';
file_put_contents("program_logs.txt","[".date('d-m-Y H:i') . "] program executed, no new mails found. \r\n",FILE_APPEND);
}
It is 1 AM and I am struggling for 3-4 hours to see what's wrong with my script...
My database has ~400 emails. I set $ChunkSize as counter for the loop and also to count which is the next chunk to be processed.
I've set some echo() to debug
echo "This is the " . $GLOBALS["ChunkSize"] . " chunk. <br>";
It should output what chunk is processed at that time.
If I disable mail() then I don't get 503 Service Unavailable but every echo() displays at the same time, not in the order of processing.
I also found out that some emails arrive, but not to everyone. Also, if some emails are sent, that means foreach() should have processed at least one chunk, that means it should display at least one echo().
I've set break 1; so every time it breaks out of foreach() it should display the echo() with the chunk number processed by foreach() but it doesn't.
What I am doing wrong?
$connection = mysql_connect($hostname, $username, $password);
mysql_select_db($dbname, $connection);
$result = mysql_query("SHOW COLUMNS FROM `Emails`");
while($row = mysql_fetch_array($result)){
$Addresses[] = $row['Field'];}
$Subject = "Test";
$Message = "
Test
";
$Headers = array( EMPTY FOR SECURITY REASONS );
$Headers = implode( "\r\n" , $Headers );
$ChunkAddresses = 50;
$EmailChunkArray = array_chunk($Addresses, $ChunkAddresses);
$ArraySize = count ($EmailChunkArray);
$ChunkSize = 0;
ChunkLoop: {
$EmailChunkArrayLoop = $GLOBALS["EmailChunkArray"];
foreach ($EmailChunkArrayLoop[$GLOBALS["ChunkSize"]] as $ToChunkLoop) {
if ($GLOBALS["ChunkSize"] <= $GLOBALS["ArraySize"]) {
mail($ToChunkLoop,$GLOBALS["Subject"],$GLOBALS["Message"],$GLOBALS["Headers"]);
echo "This is the " . $GLOBALS["ChunkSize"] . " chunk. <br>";
} else if ($GLOBALS["ChunkSize"] == $GLOBALS["ArraySize"]){
exit();}
$GLOBALS["ChunkSize"]++;
break 1;}
}
if ($GLOBALS["ChunkSize"] != $GLOBALS["ArraySize"]){
echo "Test. <br>";
goto ChunkLoop;
} else {
echo "Finished! <br>";}
Create script that will only do one thing - send mail.
sendMail.php
<?php
// Get recipient from the argv array
$recipient = $_SERVER['argv'][1];
// Mail args
$subject = 'HELLOOOOOOO';
$message = 'BLablabla';
$headers = [...]; // optional or not
// Send it
mail($recipient, $subject, $message, $headers);
And inside of Your code where You do:
mail($ToChunkLoop,$GLOBALS["Subject"],$GLOBALS["Message"],$GLOBALS["Headers"]);
Replace with:
$recipient = escapeshellarg($ToChunkLoop);
exec("php /path/to/sendMail.php ".$recipient." > /dev/null &"); // that will call mail script and will not wait when execution will end
Feel free to adapt my code examples as You wish
P.S. this solution is for cases when You don't want to pay for normal batch mail sending, mail subscription or dedicated, vps services and have just small web hosting. (:
P.S.. it's not a brilliant solution, but done for requirements provided by question author
In below code, we are first selecting users based on the admin's input from database. Then sending emails to those users. With the code it sends emails to $mail_news->addAddress('testuser#gmail.com'); test user. But for the bcc part is not working, as it doesn't send any emails to bcc email users.
foreach($email_array as $news_mail){
$mail_news->AddBCC($news_mail.";");
}
This is how we fetch user emails via form & PHP prepare statement with mysqli.
Here is the main part code:
if($msn->execute()){
$msn->store_result();
$msn->bind_result($news_mail);
while($msn->fetch()){
$email_array[] = $news_mail;
}
// echo "successful";
}
else
{
echo "database failed";
}
//--Email Sending Starts
$mail_news = new PHPMailer;
$mail_news->isSMTP();
$mail_news->Host = EMAIL_HOST;
$mail_news->SMTPAuth = true;
$mail_news->Port = EMAIL_PORT;
$mail_news->SMTPSecure = 'tls';
$mail_news->Username = EMAIL_ADD;
$mail_news->Password = EMAIL_PASS;
$mail_news->From = EMAIL_ADD;
$mail_news->FromName = 'Company Account';
$mail_news->addAddress('testuser#gmail.com');
foreach($email_array as $news_mail){
$mail_news->AddBCC($news_mail.";");
}
$mail_news->WordWrap = 50;
// $mail_news->SMTPDebug = 2;
$mail_news->isHTML(true);
$mail_news->Subject = "".$sub;
$mail_news->Body = "".$body;
$mail_news->AltBody = "".$altbody;
if(!$mail_news->send()) {
echo "Failed Sending Emails" ;
echo 'Mailer Error: ' . $mail_news->ErrorInfo;
} else {
echo "All Email sending completed" ;
}
?>
</form>
<?php
$msn->close(); // Finally closing the database
}
?>
You need to change the line
$mail_news->AddBCC($news_mail.";");
with
$mail_news->AddBCC($news_mail);
because the method addBCC() handles the semicolon by itself. You do not need to specify by your own.
this is my first time using PHP, so I'm here because I don't even know how to look for the information I want (function name's, properties, etc). As I said before, my code receives a string with two variables and uploads it to a log with the format:
Raw time data, var1, var2
So, I want to add some lines that allow the code to send an "OK" confirmation when data has been successfully posted. How can I get it?
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
echo "<pre>";
echo "hello! \n";
$file = 'measures.txt';
$time = time();
$row = "$time";
if ( isset( $_GET["T"] ) )
{
$new_measure = $_GET["T"];
echo "Temperature: $new_measure \n";
$row = $row.", $new_measure";
} else {
$row = $row.", ";
}
if ( isset( $_GET["H"] ) )
{
$new_measure = $_GET["H"];
echo "Humidity: $new_measure \n";
$row = $row.", $new_measure";
} else {
$row = $row.", ";
}
file_put_contents($file, "$row\n", FILE_APPEND | LOCK_EX);
echo "</pre>";
?>
Julio,
in your file_put_contents function you could simply echo a " OK" message if the file is successfully stored in the location you set. Now if you are trying to do email confirmation you would need to setup a mail function within your php application and have the proper smtp configurations so your server can do that.
I am assuming you have verification checks before the file is given to your file_put_contents function.
got this code that should check if url is available and also give me ping:
<?php
function test ($url){
$starttime = microtime(true);
$valid = #fsockopen($url, 80, $errno, $errstr, 30);
$stoptime = microtime(true);
echo (round(($stoptime-$starttime)*1000)).' ms.';
if (!$valid) {
echo "Status - Failure";
} else {
echo "Status - Success";
}
}
test('google.com');
?>
How do i make it so this function would be called every lets say 10minues for 1hour (6times in total) ?
I would recommend you to make use of cron jobs if you are using a Unix server or Windows Task Scheduler in the case of windows.
Like this you will be able to use programmed tasks.
In the case of using cron you could do it easily like this:
*/10 * * * * php -f your_relative_or_full_path_URL/params > /dev/null
depends: do you want to do that just once?
Then you can call the function inside a loop and use sleep() after each execution of the loop.
Do you want to do it everyday? or one specific day each week/month? use a cron.
Use a simple for-loop and the sleep command:
for ($i = 0; $i < 6; $i++) { // Run the code 6 times
test($url);
sleep(10 * 60); // Sleep 10 Minutes
}
Send Email every day in a Month. I used it in daily backup mail..
<?php
ignore_user_abort(true); //if page is closed its make it live
for($i=0;$i<=30;$i++)
{
$to = "someone#exmple.com";
$subject = "Test mail $i";
$message = "Hello! This is a simple email message.";
$from = "from#example.com";
$headers = "From:" . $from;
mail($to,$subject,$message,$headers);
sleep(24*60);//send mail in every 24 hour.
}
?>