send mail via php yii until success on time - php

i have php function that send mail on special time ever 7 days but when i send mail its sometimes not sent because server busy or not available ,my question is how to try send my email many times when its something wrong every 10 minute until its send success
private function sendEMailMessage($args) {
$failed = true;
for($i = 0; $i < 5 && $failed; $i ++) {
$failed = Utilities::sendEMailMessage ( $args ) != '';
if ($failed) {
sleep ( 15 );
}
}
}
//its this work or not ???

The another way you can do this is setting a flag in database table. Based on the flag value you can send/resend the email. On successful sending of email you can delete or reset the flag .

The best way to deal with this problem would be to set up cron jobs for every 7 days.And for the mail sometimes getting not sent purpose you could use this,
if (Yii::$app->mailer->getTransport()->isStarted()) {
Yii::$app->mailer->getTransport()->stop();}
Yii::$app->mailer->getTransport()->start();
If this is included in your yii app then once the mail is sent it should clear the ssl socket layer and open a fresh socket again for the next time.With the combined use of these I think it should work.

Related

How to send x number of email using phpMailer?

I have a job site (in CI) and there can be x number of jobseekers.What i have to do is send revalent jobs according to users job category and location.So there is different message for different jobseeker.
i am using phpMailer to send email for now i have done
$subject = 'Revalent Jobs For Your Profile';
foreach ($job_receiving_users as $job_receiving_user){
$this->send_email->send_email(FROM_NOREPLY_EMAIL,ORG_NAME,$job_receiving_user['email'],$job_receiving_user['username'],$subject,$job_receiving_user['message']);
$time = time() + 10;
while( time() < $time){
// do nothing, just wait for 10 seconds to elapse
}
}
(There is phpMailer email sending method inside library send_email)
There is limit of 200 email per hour from server or can extend it to 500.
What i want to know is this good way to send email?
if i keep 10secod gap between every email will it keep my server busy.All sql actions were done above this code and $job_receiving_users is array of user email,message and username extracted above.
Base your code on the mailing list example provided with PHPMailer
What you're doing in your loop is called "busy waiting"; don't do it. PHP has several sleep functions; use them instead. For example:
$sendrate = 200; //Messages per hour
$delay = 1 / ($sendrate / 3600) * 1000000; //Microseconds per message
foreach ($job_receiving_users as $job_receiving_user) {
//$this->send_email->send_email(FROM_NOREPLY_EMAIL,ORG_NAME,$job_receiving_user['email'],$job_receiving_user['username'],$subject,$job_receiving_user['message']);
usleep($delay);
}
This will cause it to send a message every 18 seconds (200/hour), and the use of the sleep function will mean it consumes almost no CPU while it's waiting.

How can I send an email to lots of users using a proper way in CodeIgniter 3

I need some advice because I am building a subscription module. And I have a list of so many emails. Let say 1052 emails. And I have a code like this:
$email_list = $this->getClientEmails(); //all email for now returns 1052 valid emails
$valid_email = array();
$invalid_email = array();
if(count($email_list) > 0) {
for($x = 0; $x < count($email_list); $x++) {
if(valid_email($email_list[$x]['email'])) {
$valid_email[] = $email_list[$x]['email'];
}
//get all invalid emails
/*else {
$invalid_email[] = array(
'id' => $email_list[$x]['id'],
'email' => $email_list[$x]['email']
);
}*/
}
}
$email_string = implode(',', $valid_email);
$this->email->set_mailtype("html");
$this->email->from($from, 'Sample Admin');
$this->email->to($email_string); //send an email to 1052 users
$this->email->cc('test#sampleemail.com.ph');
$this->email->subject($subj);
$this->email->message($content);
$send_mail = $this->email->send();
if($send_mail) {
fp('success');
} else {
fp('failed');
}
Is it fine if I send an email like this? Or should I make a loop to send my email to different users? Means I will not use my imploded string. I will do the sending once in every week. And also what if the sending of email suddenly stops in the middle what should I do? Do I need to resend it again? Or should I make a column in my table that will update if the email is sent or not?
Can you give me some advice about this? That's all thanks.
Okay because you have a mailing list the first thing that i would recommend is that you push the script to background. Use selinium or cron for the same that way page render won't get stuck.
Once done You can send emails either way, send to multiple people or one at a time, both of them are valid and won't cause any problem. The point you need to consider here is the SMTP connection that you maintain.
If you are sending them all individually, you don't want to close connection to SMTP server and reconnect every time to send the mail which would only cause the overhead.
I should say that from your case the most valid way to send email is make a queue on some database preferably redis and have a task handle them in background (cron job if you are on cpanel or selinium if you own the server)
Finally this is a part that you might wanna test out. Because you have a mailing list i am guessing you don't want people to see through your whole list so check the headers when you are sending mails to all at once and if you don't see email from other users , you are good to go else send to each of them separately.
Also one final thing, emails not being delivered is usually bounced which may reflect bad on your server so have a script that flags emails that are constantly rejected and stop sending mails to the same or your ip address might end with bad repo and mails might end up in spam.
Have you thought of using PHPMailer as a library on your CodeIgniter installation?
You could just do it like this:
if(count($email_list) > 0) {
for($x = 0; $x < count($email_list); $x++) {
if(valid_email($email_list[$x]['email'])) {
$mail->addAddress($email_list[$x]['email'], $x);
}
}
}
Please refer to this example on how to use PHPMailer.
I hope this helps, or at least that it gives you a different perspective on how can this be done.
Referring to:
Or should I make a column in my table that will update if the email is sent or not?
Yes, I think that if you want to control if an email has been sent you should use a 1 character field on your table as a "flag" to corroborate that the email has been sent to your users.

How to send a large email?

$i = 1;
foreach ($recipients as $email => $name) {
$mail->ClearAddresses();
$mail->AddBCC($email, $name);
if (!$mail->send()) {
$send = 0;
} else {
$send = 1;
}
$query = "INSERT INTO `newsletter_send`(`email`, `id_newsletter`, `date`, `send`) VALUES ('$email',$id_newsletter, NOW(),$send) ";
$stmt = $link->prepare($query) or die('error');
$stmt->execute();
$mail->clearAllRecipients();
if (($i % 100) == 0) {
sleep(60);
}
$i++;
}
What is the best way to send a large emails without sleep() and without to wait the page to finish loading? In addition to the cron job you have other ideas ?
EDIT: I have 680 users who will receive the email, but after a while I get 500 Internal Server Error.. why? It maybe time_limit?
Message queues.
beanstalkd is a good solution.
You can then use a SDK like pheanstalk to handle the queue and its jobs.
EDIT: If you have restricted access to your server (for example, if you are using a shared hosting) message queues as a service are also an option.
IronMQ
CloudAMQP
AWS (Amazon Web Services) SQS
A good way to send a large amount of emails at a fast pace is to have a lot of worker scripts doing the job instead of 1 php page (GiamPy gave a good example for one of the ways that can be done and I won't mention it since I don't want to be redundant).
One simple (though somewhat hacky) option is: for you to make 20 php scripts in a file. You could name them mailer1.php, mailer1.php, ..., mailer20.php. Then, you could create a folder called mail and put two files inside:
mail/config.txt
and
mail/email.txt
Inside mail/config.txt, you would include the following lines of text:
T
15
where the first line has a T for TRUE meaning you want the mailers to send the mail out as fast as they can in intervals of 15 seconds each. You can obviously change the interval time as well to whatever you like.
And in mail/email.txt you would have the complete email you want to send
After having done all that you make the mailer files. You can make 1 first, write the code, and then copy paste it 19 times to have 20 scripts in total. The code inside could look something like this:
<?php
$pathconfig = "mail/config.txt";
$pathemail = "mail/email.txt";
$email = file_get_contents($pathemail);//now you have the email saved
$filehandleconfig = fopen($pathconfig, "r");
$bool = trim(fgets($pathconfig));
$sleeptime = (integer) trim(fgets($pathconfig));
fclose($filehandleconfig);
while ($bool === 'T')
{
//... code that sends the email
//recheck if 'T' is still 'T':
$filehandleconfig = fopen($pathconfig, "r");
$bool = trim(fgets($pathconfig));
fclose($filehandleconfig);
sleep($sleeptime);
}
?>
So what the previous code would basically do is extract the email that needs to be sent at the beginning, and also extract the time it will sleep after sending an email, and if it should continue to send emails.
What that means is that the mail/config.txt file is your controlpanel, and if you change 'T' to be anything else that 'T' (like 'F' for instance), then all the scripts will terminate.
The downside to this option is that it's a bit hacky, though the upside is that it can be developed in a matter of minutes.

Add Emails to a Database when Received (PHP)

I want to make it so users can automatically subscribe to my mailing list by sending a email with a special body.
Example:
Send "subscribe" to "email#mywebsite.com" and a PHP script is automatically executed to add them to a database.
Send "unsubscribe" to "email#mywebsite.com" and the PHP script removes them.
I have the script to add/remove them done easily, but what I need help with is how to actually implant the email receive to execute the function...If that makes sense.
Using cPanel/WHM, can do a cron job.
Thanks a lot for the help
The solution can be the following code (i didn't check it):
if( $imap ) {
//Check no.of.msgs
$num = imap_num_msg($imap);
//if there is a message in your inbox
if( $num >0 ) {
//read that mail recently arrived
if (imap_qprint(imap_headerinfo($imap, $num)) == 'subscribe'){
// code for add user to database
};
if (imap_qprint(imap_headerinfo($imap, $num)) == 'unsubscribe'){
// code for delete user to database
}
}
//close the stream
imap_close($imap);
}
?>

Maintaining counter value in PHP

I'm working on a system where an android app needs to send periodic updates to a server to say it is running okay. If 4 checks pass and an update hasn't been sent, a text message needs to be sent. I want to use a counter in the PHP file that checks how many 'checks' have passed without an update. However every time the android application contacts the server the counter is reset and never increases. I have it working but I don't want the message to be sent until the counter is 4. Does anyone have any suggestions on how to retain the value of the counter when the file is 'reopened'. Thanks.
<?php
//...
// check the value sent from the android application
if(isset($_REQUEST['alert'])){
echo "alert";
// everything is ok, reset the counter
$counter = 0;
}
else echo "no alert";
// increase the counter
$counter++;
if($counter >= 4) {
while($row = mysql_fetch_array($result)) {
$phNum = $row['mobile'];
}
// an update has not been sent in 4 attempts, send a text message
send_sms($phNum);
}
//...
?>
Perhaps you could:
Use SharedPreferences in Android App which would keep count of checks? then send it to server to say all 4 checks were passed?
PHP script is executed from beginning every time you visit website, another method would be to use sessions but that will get a bit messy, and another way: when request is called, it would send your data + device ID (unique ID to each device), then it would add number of checks into database and keep track of checks for each device, that would slow down your execution time by not that much.
But as I said already, Shared Preferences would work.
If your android app is properly sending and storing cookies you can use the php $_SESSION or $_CCOKIE variable for persistent data.

Categories