Iterate array then reset again multiple array - php

I want to iterate array then It should be reset again in PHP .
The following logic I want to implement
I have an array of smtp and a second array from which I just want to send
email once per smtp .
Actually I have a list of array for which I want to send email but I have
few smtp hosts .
I am iterating a list of array in foreach loop.
I have a smtp array in which I have defined certain limit to send email.
function sendmail_test(){
return "Sent<br/>";
}
$email_arrays=array(
'test1#gmail.com',
'test2#gmail.com',
'test3#gmail.com',
'test4#gmail.com',
'test5#gmail.com',
'test6#gmail.com',
);
$smtp_array=array(
'gmail_smtp#gmailsmtp.com'=>10,
'yogya_smtp#yogyasmtp.com'=>15
);
$smtp_count=count($smtp_array);
$smtp_counter=0;
for($i=0;$i<=$smtp_count;$i++){
foreach($email_arrays as $ek=>$ev){
print_r($smtp_counter);
echo sendmail_test();
}
$smtp_counter++;
}
Actually I want exactly like this.
I have currently have two smtp in $smtp_array
First email should be fired by like this smtp
test1#gmail.com - >'gmail_smtp#gmailsmtp.com'
And second email should be fired by like this
test2#gmail.com',->'yogya_smtp#yogyasmtp.com'
and then third email should be fired like this
test3#gmail.com - >'gmail_smtp#gmailsmtp.com'
which Is then reset and will use first smtp in $smtp_array ..
I hope you will get my point now.

If you want to go though all the smtp servers and reset to the start when you had the last one, you might use current, end, reset, and next.
To get the value for the smtp, you could use key You can then add an smtp server to the list as well.
For example:
function sendmail_test()
{
return "Sent<br/>";
}
$email_arrays = array(
'test1#gmail.com',
'test2#gmail.com',
'test3#gmail.com',
'test4#gmail.com',
'test5#gmail.com',
'test6#gmail.com',
);
$smtp_array = array(
'gmail_smtp#gmailsmtp.com' => 10,
'yogya_smtp#yogyasmtp.com' => 15
);
$lastElement = end($smtp_array);
reset($smtp_array);
foreach ($email_arrays as $em) {
$current = current($smtp_array);
//sendmail_test();
echo "Send email $em with smtp: " . key($smtp_array) . PHP_EOL;
next($smtp_array);
if ($lastElement === $current) {
reset($smtp_array);
}
}
Result:
Send email test1#gmail.com with smtp: gmail_smtp#gmailsmtp.com
Send email test2#gmail.com with smtp: yogya_smtp#yogyasmtp.com
Send email test3#gmail.com with smtp: gmail_smtp#gmailsmtp.com
Send email test4#gmail.com with smtp: yogya_smtp#yogyasmtp.com
Send email test5#gmail.com with smtp: gmail_smtp#gmailsmtp.com
Send email test6#gmail.com with smtp: yogya_smtp#yogyasmtp.com
Php demo

You can approach this as following
$hosts = array_keys($smtp_array);
foreach($email_arrays as $k => $v){
$email = $v;
$host = $hosts[$k%2];
echo $email.'----'.$host;echo '<br/>';// use $email and $host to send the email
}

Related

Mailgun call to send message to multiple recipients is not returning to caller - example provided

We are attempting to send an email to multiple recipients using the Mailgun PHP API.
We are running MG PHP lib version 2.8.1.
Our code does the following:
note: email address and domain changed for privacy reasons
log_debugger('g1', 'g1');
$params = array(
'from' => $msg_org . " <" . EMAIL_SENDER . ">",
'to' => array('joe#gmail.com'),
'subject' => 'Hey %recipient.first%',
'text' => 'If you wish to unsubscribe, click http://example.com/unsubscribe/%recipient.id%',
'recipient-variables' => '{"joe#gmail.com": {"first":"Joe", "id":1}}'
);
log_debugger('g1', 'g2');
# Make the call to the client.
$mgresult = $mgClient->messages()->send(MAILGUN_DOMAIN, $params);
log_debugger('g1', 'g3');
// if the email was accepted by Mailgun then indicate the member message was delivered
if ($mgresult->http_response_code >= 200 && $mgresult->http_response_code < 300) {
log_debugger('mgr', $mgresult->http_response_code);
// else the email was not accepted by mailgun so indicate the member message failed to be delivered
} else {
log_debugger('g1', 'g4');
}
The call is successfully getting to MG, but we are not getting any return from MG. We have been sending to MG successfully for sometime and now we are attempting to send to multiple email addresses at one time. Below is the data we are passing in as recorded by our debug log.
2020-08-14 12:47:01 g1
2020-08-14 12:47:01 g1
2020-08-14 12:47:01 g1
2020-08-14 12:47:01 g2
Here is the MG documentation - Notice the error: messages()-send should be messages()->send
require 'vendor/autoload.php';
use Mailgun\Mailgun;
// Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = "YOUR_DOMAIN_NAME";
$params = array(
'from' => 'Excited User <YOU#YOUR_DOMAIN_NAME>',
'to' => array('bob#example.com, alice#example.com'),
'subject' => 'Hey %recipient.first%',
'text' => 'If you wish to unsubscribe, click http://example.com/unsubscribe/%recipient.id%',
'recipient-variables' => '{"bob#example.com": {"first":"Bob", "id":1},
"alice#example.com": {"first":"Alice", "id": 2}}'
);
// Make the call to the client.
$result = $mgClient->messages()-send($domain, $params);
Any help getting this to work would be greatly appreciated. Logged a ticket with MG, but no reply as of yet.
Method documented by MG for sending message is not quite correct. I had to change the call from:
$mgresult = $mailgun_client->messages()->send(MAILGUN_DOMAIN, array(
to:
$mgresult = $mailgun_client->sendMessage(MAILGUN_DOMAIN, array(

Php code to send message to multiple recipient with different message body

I'm trying to send messages to multiple recipients with different message body but I don't know if my script has any error. The problem is when I execute this below code, only one user email will receive message. If I try it again another one will get a message. I want all the emails in the array to receive the message with individual message body. And also I noticed that my script takes long to complete execution. Is there a better way to get this working as expected?
PHP
<?php
$conn_handler->prepare('
SELECT * FROM food_orders fo
INNER JOIN our_chefs oc
ON oc.chef_private_key = fo.order_chefpkey
WHERE fo.order_id = :currentorder AND fo.order_userid = :order_userid
ORDER BY fo.order_chefpkey
');
$conn_handler->bind(':currentorder', $lastOrderId);
$conn_handler->bind(':order_userid', $buyerid);
$conn_handler->execute();
$getFoodOrders = $conn_handler->getAll();
if( !isset($_SESSION['completed_'.$lastOrderId]) ) {
$creatProducts = array();
$email_list = array();
/*Here i loop on current orders*/
foreach($getFoodOrders as $row) {
//Create an array of chef emails
$email_list[$row->chef_private_key] = $row->chef_email;
//Create an array of items based on chef private key
$creatProducts[$row->order_chefpkey][] = array(
'o_name' => $row->order_foodname,
'o_pid' => $row->oder_foodid,
'o_price' => $row->order_price,
'o_currency' => $row->currency,
'o_qty' => $row->order_qty,
'o_size' => $row->order_size,
'o_img' => $row->order_image,
);
}
//Here i loop through the above chef emails
foreach($email_list as $key => $val) {
$productBuilder = null;
//Here i create html for products based on chef keys
foreach($creatProducts[$key] as $erow) {
$productBuilder .= '<div><b>Product Name:</b> '.$erow['o_name'].'<br/></div>';
}
//Here i send email to each chef with their individual products created above
$sourcejail->sendMail(
$val, //Send TO
null, //Send Bcc
null, //Send CC
null, //reply To
1, //Something
'Your have received new order ('.$lastOrderId.')', //Subject
$productBuilder //Message body
);
}
$_SESSION['completed_'.$lastOrderId] = true;
}

check if domain exists using PHP PEAR Mail class

I noticed that my server has been returning this error when trying to send email to an invalid domain:
Standard Message: Failed to set sender: user#invaliddomain.coom [SMTP: Invalid response code received from server (code: 553, response: 5.1.8 ... Domain of sender address user#invaliddomain.coom does not exist)]
Standard Code: 10004
DBMS/User Message:
DBMS/Debug Message:
Is there a way to check the domain first before attempting to send the email? I have a feeling I could also handle this on the SMTP server end by squelching this error, but I like the idea of being able to test an email domain first before sending it. Thanks for your ideas!
Here is the pertinent code just for reference (variables are filtered in from a form):
$headers['To'] = $to_address;
$headers['From'] = $from;
$headers['Reply-To'] = $from;
$headers['Subject'] = $subject;
$this->setHTMLBody($body);
$body = $this->get(array('text_charset' => 'utf-8'));
$headers = $this->headers($headers, true);
$message =& Mail::factory('smtp');
$mail = $message->send($to_address,$headers,$body);
You could use Net_DNS2 to determine if the domain exists and if so, send the email on it's merry way.
include "Net/DNS2.php";
$r = new Net_DNS2_Resolver();
try {
$result = $r->query($domain, 'MX');
} catch(Net_DNS2_Exception $e) {
$result = null;
}
if ($result !== null) {
// send email...
}
Naturally, I'd suggest some level of caching so you aren't repeating lookups.

Why it takes so long to send multiple emails with Sendgrid?

I have a sport betting tips website and on every tip that i publish i send an email to every user (about 700 users in total) with SendGrid. The problem comes with the delivery time. The email is delayed even half an hour from the time of send.
Does anyone know why and how could i fix it?
I am sending it with SMTP.
Here is some of my code:
$catre = array();
$subiect = $mailPronostic['subiect'];
$titlu = $mailPronostic['titlu'];
$text = $mailPronostic['text'];
$data = new DateTime($this->_dataPronostic);
foreach($users as $user){
array_push($catre, $user->_emailUser);
}
$data = urlencode($data->format("d-m-Y H:i"));
$echipe = urlencode($this->_gazdaPronostic." vs ".$this->_oaspetePronostic);
$pronostic = urlencode($predictii[$this->_textPronostic]);
$cota = $this->_cotaPronostic;
$mesaj = file_get_contents("http://plivetips.com/mailFiles/mailPronostic.php?text=".urlencode($text)."&titlu=".urlencode($titlu)."&data=$data&echipe=$echipe&pronostic=$pronostic&cota=$cota");
//return mail(null, $subiect, $mesaj, $header);
$from = array('staff#plivetips.com' => 'PLIVEtips');
$to = $catre;
$subject = "PLIVEtips Tip";
$username = 'user';
$password = 'pass';
$transport = Swift_SmtpTransport::newInstance('smtp.sendgrid.net', 587);
$transport->setUsername($username);
$transport->setPassword($password);
$swift = Swift_Mailer::newInstance($transport);
$message = new Swift_Message($subject);
$message->setFrom($from);
$message->setBody($mesaj, 'text/html');
$numSent = 0;
foreach ($to as $address => $name)
{
if (is_int($address)) {
$message->setTo($name);
} else {
$message->setTo(array($address => $name));
}
$numSent += $swift->send($message, $failures);
}
Thx.
how long does the script take to run? I have a feeling the script is taking a long time. If that's the case, I think it is because you are opening a connection for each message.
With SendGrid, you can send a message to 1000 recipients with one connection by using the X-SMTPAPI header to define the recipients. The easiest way to do this to use the official sendgrid-php library and use the setTos method.
Recipients added to the X-SMTPAPI header will each be sent a unique email. Basically SendGrid's servers will perform a mail merge. It doesn't look like your email content varies with each user, but if it does, then you may use substitution tags in the header to specify custom data per recipient.
If you don't want to use sendgrid-php, you can see how to build the header in this example.

Sending mass email SLOW with PHP PEAR Mail and ALT-N Mdaemon pro

We have a growing mailing list which we want to send our newsletter to. At the moment we are sending around 1200 per day, but this will increase quite a bit. I've written a PHP script which runs every half hour to send email from a queue. The problem is that it is very slow (for example to send 106 emails took a total of 74.37 seconds). I had to increase the max execution time to 90 seconds to accomodate this as it was timing out constantly before. I've checked that the queries aren't at fault and it seems to be specifically the sending mail part which is taking so long.
As you can see below I'm using Mail::factory('mail', $params) and the email server is ALT-N Mdaemon pro for Windows hosted on another server. Also, while doing tests I found that none were being delivered to hotmail or yahoo addresses, not even being picked up as junk.
Does anyone have an idea why this might be happening?
foreach($leads as $k=>$lead){
$t1->start();
$job_data = $jobObj->get(array('id'=>$lead['job_id']));
$email = $emailObj->get($job_data['email_id']);
$message = new Mail_mime();
//$html = file_get_contents("1032.html");
//$message->setTXTBody($text);
$recipient_name = $lead['fname'] . ' ' . $lead['lname'];
if ($debug){
$email_address = DEBUG_EXPORT_EMAIL;
} else {
$email_address = $lead['email'];
}
// Get from job
$to = "$recipient_name <$email_address>";
//echo $to . " $email_address ".$lead['email']."<br>";
$message->setHTMLBody($email['content']);
$options = array();
$options['head_encoding'] = 'quoted-printable';
$options['text_encoding'] = 'quoted-printable';
$options['html_encoding'] = 'base64';
$options['html_charset'] = 'utf-8';
$options['text_charset'] = 'utf-8';
$body = $message->get($options);
// Get from email table
$extraheaders = array(
"From" => "Sender <sender#domain.com>",
"Subject" => $email['subject']
);
$headers = $message->headers($extraheaders);
$params = array();
$params["host"] = "mail.domain.com";
$params["port"] = 25;
$params["auth"] = false;
$params["timeout"] = null;
$params["debug"] = true;
$smtp = Mail::factory('mail', $params);
$mail = $smtp->send($to, $headers, $body);
if (PEAR::isError($mail)) {
$logObj->insert(array(
'type' => 'process_email',
'message' => 'PEAR Error: '.$mail->getMessage()
));
$failed++;
} else {
$successful++;
if (DEBUG) echo("<!-- Message successfully sent! -->");
// Delete from queue
$deleted = $queueObj->deleteById($lead['eq_id']);
if ($deleted){
// Add to history
$history_res = $ehObj->create(array(
'lead_id' => $lead['lead_id'],
'job_id' => $lead['job_id']
)
);
if (!$history_res){
$logObj->insert(array(
'type' => 'process_email',
'message' => 'Error: add to history failed'
));
}
} else {
$logObj->insert(array(
'type' => 'process_email',
'message' => 'Delete from queue failed'
));
}
}
$t1->stop();
}
hard to tell. You should profile your code using xdebug to pintpoint low hanging fruit.
Also I think you might consider using a message queue to process your e-mail(redis/beanstalkd/gearmand/kestrel) asynchronous or using third-party dependency like for example google app engine which is very cheap($0.0001 per recipient/first 1000 emails a day free)/reliable. That will cost you about 10 cent a day when considering your load.
you're facing a couple of different problems.
1.) to send a lot of emails you really need a mailer queue and several mail servers to get mail from that queue and process the mail in turn (round robin style <-- this link is related but not perfectly specific to your needs. [It's enough to get you started]).
2.) your mail is likely not getting to Hotmail/yahoo for one of 2 reasons.
a.) you don't have RDNS properly configured and when the look for your IP (from the heder) it is not mapping back right to your domain in the header. or
b.), you've already been flagged as a spammer on SPAMHAUS or whatever the blacklisting service du jour is.

Categories