I want to send emails where the data is from a php/mySQL query.
I know that html will render in the email but i don't think the php codes will.
So is there any way where i can send emails with content queried from a mySQL DB ?
I already search here, there is one topic that covers it but the person who advised suggested a pdf export or to use a 3rd party tool which in my case are not applicable.
Thank you for the help guys :)
Use PHPMailer to generate the email on the server. It makes it very easy to generate multi-part messages (plaintext + html, with attachments and embedded/inline images). Basically:
// set up PHPMailer
$mail = new PHPMailer();
$mail->SetFrom('you#yourserver.com');
$mail->AddReplyTo('you#somewhereelse.com');
$mail->Subject('Your profile');
$mail->IsHTML(TRUE);
// do your database query
$con = connect_to_database();
$stmt = run_database_query($con, "SELECT ... FROM ...");
$data = fetch_from_database($stmt);
// set the email address
$mail->AddAddress($data['email'], $data['fullname']);
// html content for smart email clients
$html = <<<EOL
<h1>Welcome</h1>
<p>Your username is {$data['username']}.</p>
EOL;
// plain text alternate content
$text = <<<EOL
Welcome
Your username is {$data['username']}.
EOL;
// add the content to the mail
$mail->MsgHTML($html);
// add alternate content
$mail->AltBody($text);
// send the mail
if ($mail->Send()) {
// mail sent correctly
} else {
die("Uhoh, could not send to {$mail['email']}:" . $mail->ErrorInfo);
}
To avoid spam issues you can wrap the PHPMailer in a class and instantiate that at every e-mail address read from the database table.
For each email address you can create a new instance and do kind of a ->setMailAddr($mail,$fullName) and after send the e-mail destroy this instance.
The ideal is to place a new instance at every POST. In this case, you can put a FORM into the page.
Related
I don't use PHP that often but when I do and I need to write a function to send E-Mails, I just used the mail() function. I have used it on a shared hosting service and I always received the E-Mails from a... well... not an account? A bot? It didn't even have an E-Mail address.
And that's what I want to achieve at this very moment - send an E-Mail to me without really connecting to a SMTP server or going through authentication. How can be that done with PHPMailer? Is it even possible in my case? And if you somehow got my question, how are such E-Mails even called; the ones that... aren't sent by... well... an E-Mail account?
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'PHPMailer-master\src\Exception.php';
require 'PHPMailer-master\src\PHPMailer.php';
require 'PHPMailer-master\src\SMTP.php';
$mail = new PHPMailer();
$mail->FromName = "A random name";
$mail->addAddress("myemail#gmail.com", "Recepient Name");
$mail->isHTML(true);
$mail->Subject = "Subject is here";
$mail->Body = "Hello, <br>test body ";
if(!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message has been sent";
}
?>
This did make me laugh a bit...
No, emails can't just magically spring into existence, but there isn't necessarily a direct correlation between email user accounts and addresses.
When you send from a shared hosting account by calling mail(), the mail server knows the account you're sending from, and sometimes doesn't require authentication as a result. This for example is how GoDaddy operates. Unfortunately this approach is very prone to abuse because there is often little preventing you from flat-out lying about who you are. This is why such services are usually a) terrible and b) extremely unreliable for actually delivering messages.
If you don't specify a "from" address, the server will usually make one up from information it does have – typically your user account name, or the name of the user running the script (e.g. www-data), and the hostname of the server you're on, often something like randomnumber.hostingprovider.example.com. Look at the headers of messages you've sent before, and you'll probably see something like that.
Sometimes this address can be the same for all users on a given shared server, so your delivery reputation can depend on what others are sending, which could well be spam, phishing, malware, etc.
This vagueness is terrible for deliverability, so if you host your contact form on such a system, expect messages from it to end up in a spam folder.
If you use SMTP to send via a "proper" account you gain a lot more control and reliability, but unfortunately some hosting providers (GoDaddy again) block outbound SMTP and force you to use their mail servers. This is a way of saying that if you want to send email that will be delivered, use a decent hosting provider.
Once you get control over your sending, you can choose exactly what addresses messages are sent from, subject to authentication constraints including things like SPF, DKIM, and DMARC, but that's another story.
To my knowledge it is possible and have it work correctly each time. In the last year I found that the e-mails I sent using the mail() function would immediately go into my spam box (as well as the junk box of others) causing great confusion. I upgraded to PHPMailer to solve this and I have never set it up to use SMTP and works just fine.
The code I have is:
$mail = new PHPMailer(true);
$html = $email->get(); // This gets a standard HTML Template to use as the base of the e-mail.
$title = 'Title for Inside the HTML';
$subject = 'The E-mail Subject';
$html = str_replace('[title]',$title,$html); //Use this to replace the [title] element in my HTML Template with $title.
$html = str_replace('[date]',date("F j, Y g:i A"),$html); // Again, replaces [date] in the HTML Template with the current date and time.
$body = 'Hello My Good Friend,<br>This is just a simple <strong>HTML Message</strong><br><br>Thank you.';
$html = str_replace('[body]',$body,$html); //Add my HTML Message to the HTML Template.
try {
//Recipients
$mail->setFrom('noreply#example.com', 'My Organization');
$mail->addAddress($row["email"], $row["fullname"]); // Add a recipient
//Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $html;
$mail->AltBody = strip_tags($html,'<br>');
$mail->send();
//Return Success Message
$rMsg .= '<div class="alert alert-success">
<strong>Success: </strong> We have e-mailed the warning.</div>';
} catch (Exception $e) {
$rMsg .= '<div class="alert alert-danger">
<strong>Error: </strong> There was an error e-mailing the warning.</div>';
}
I am sending emails using an online form via phpmailer and trying to use a for each loop to customize the body, specifically for an unsubscribe button. I am currently only using two of my personal emails with no encryption for testing purposes. I will add encryption once this actually starts to work as it should.
My php code:
$mail = new PHPMailer;
/*php mailer settings*/
//All settings for php mailer here - working fine, email sends
/*for each loop to send bcc to each email and customize body*/
//array of emails - really loading from database with while loop
$subs_email("email1#example.com","email2#example.com");
foreach ($subs_email as $email) {
$mail->addBCC($email);
$mail->Body = '<p>This is the body text</p>Unsubscribe';
}
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
}
Using a variation of the code above the email will send (bcc) to the two emails in the array but all emails will get the same unsubscribe link/email address. Note email1# is used both times.
Email to email address 1:
Body text looks good.
Unsubscribe
Email to email address 2:
Body text looks good.
Unsubscribe
This is obviously not what I want. When I do testing and just echo out the for each loop text on a blank page it shows each custom unsubscribe link as it should, one for each email address.
Any help is appreciated, and let me know if you need more or .
working code created based on answer
Main issue was using addBCC instead of addAddress
foreach ($subs_email as $email) {
$mail->addAddress($email);
$mail->Body = '<p>This is the body text</p>Unsubscribe';
if (!$mail->send()) {
echo "Mailer Error" . $mail->ErrorInfo . '<br />';
break; //Abandon sending
}
// Clear all addresses and attachments for next loop
$mail->clearAddresses();
}
This is how BCC works - the same message is sent to all recipients. You need to send a separate message to each recipient, as described in the mailing list example provided with PHPMailer.
For efficiency, you should create a single instance before your loop, iterate over your list, while setting the body differently for each message (the code you have is fine, if you want more flexibility perhaps use a templating system), send the message, then clear the recipient list so the next message only gets sent to one address. It also helps to use SMTP keepalive to increase throughput. The example script does most of this.
Your approach it's incorrect because you are sending "one" mail with an N recipients you have to use addAddress and clearAddresses() after sent
<?php
foreach($subs_email as $email){
$mail->addAddress($email);
$mail->Body = '<p>This is the body text</p>Unsubscribe';
$mail->send();
$mail->clearAddresses();
}
i used $mailer->ClearAllRecipients()
<?php
foreach($subs_email as $email){
$mailer->isHTML(true);
$mailer->CharSet = 'UTF-8';
$mailer->addAddress($email);
$mailer->Body = '<div>This is the body text</div>Unsubscribe';
$mailer->send();
$mailer->ClearAllRecipients()
}
I created a members only based website and when I post new articles, (similar to blog post), I use phpmailer to send an email out to all the members that requested email to be sent to them.
The email contains the new articles content. Title, description etc..
I'm in beta testing stage right now, and with only 3 email accounts it takes about 9 seconds to send out the 3 email when I make a new post. About 3 seconds per email.
I expect to get around 100 users on this site, which would = about 5 minutes to send out all those emails.
Question
Is there a way I can hook up a real time progress bar to show how much time is left when sending the emails?
My setup is like this:
I have my form that is connected to this action script.
<?php
include($_SERVER['DOCUMENT_ROOT'] . "/core/init.php");
// new data
$title = $_POST['title'];
$description = $_POST['description'];
// query
$addnotice = DB::getInstance()->insert('table1', array(
'title' => $title,
'description' => $description,
));
$id = isset($_POST['id']);
$users = DB::getInstance()->query("SELECT id, title, description FROM table1");
$users = DB::getInstance()->query("SELECT email FROM table2 WHERE notify= 'Yes'");
foreach($users->results() as $u){
User::sendNotification($u->email, $title, '<strong><h2>'.$title.'</h2></strong><p>'.$description.'</p>');
}
Session::flash('newarticle', '<h3 class="white-tx" align="center">The article has been added!</h3>');
Redirect::to('sitepage.php');
?>
The User::sendNotification comes from my user class file that looks like this.
public function sendNotification($to, $subject, $body) {
require_once 'class.phpmailer.php';
$from = "notifier#*******.com";
$mail = new PHPMailer();
$mail->IsSMTP(true); // use SMTP
$mail->IsHTML(true);
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Host = "host***.*******.com"; // SMTP host
$mail->Port = 465; // set the SMTP port
$mail->Username = "notifier#******.com"; // SMTP username
$mail->Password = "********"; // SMTP password
$mail->SetFrom($from, 'Email Robot');
$mail->AddReplyTo($from,'Do Not Reply');
$mail->Subject = $subject;
$mail->MsgHTML($body);
$address = $to;
$mail->AddAddress($address, $to);
$mail->Send();
}
A real time progress bar would be Ideal, but I would even settle for an animated .gif loading image.
Which I tried by adding this to the action script:
echo '<table align="center" width="100%" height="100%" border="0"><tr align="center" valign="center"><td><img src="images/sending.gif"></td></tr></table>';
But that wasn't even recognized and rolled right past the sending.gif image and posted the article to the website and sent the emails.
I've searched Google for tutorials on the subject, but came up dry.
Any thoughts on this situation would be greatly appreciated.
I'd suggest to use the BCC of only one email if you do not send personalized mails.
If you want to go for the progress bar, here's a sketch of one way you could go:
Add a database table notifications with fields user_id, notice_id
Insert one row for every user WHERE notify= 'Yes' (why not BOOL here?) and new notice
Have a cronjob poll this table every now and then sending the mails (by fetching the appropriate info from the user and notice table) and removing the respective pending rows
Provide a script returning the current number of pending notifications (json) (num rows of the notification table)
Use JS (i.e. jquery) for periodic updates (http query for the aforementioned script)
(You could also have a boolean field sent if you do not want to delete the rows from the notification table but want to track the notifications.)
You could have:
a submit.php where you insert the required notifications into the table
a mail sending cronjob (i.e. php script or whatever) that removes the pending rows after sending
a poll.php where you provide the current number of rows of the notifications table in JSON format.
a status.php where you periodically request the data from poll.php and update the page accordingly
You can show a progress bar - support for it was introduced in PHP 5.2 - driven by polling it from Javascript. This nice example shows how you can use it with both PHP and jQuery parts. That example is monitoring a file upload, but you can alter it to return anything that changes over time, for example a count while sending your emails in a loop.
As others have mentioned, if you're sending more than a few messages, you need to do it entirely asynchronously as a page load is really not the time to do long operations. For queues, I recommend beanstalkd with Pheanstalk. It doesn't make any difference what email sending class you use as they can all be operated this way (though I'm obviously partial to PHPMailer!).
Your loop is also quite wasteful - there's no need to create, configure and destroy the mailer instance for every message - if your messages have much in common, you can make it much simpler.
I'm a newbie in PHP. My goal is to send an email to the user registered in my system.
Here is my code:
$msg= " Hi $gen./$lName, copy and paste this code in order to activate
your account copy and paste this code:$num" ;
$email = "$emailadd";
$name= "GoodFaith Network Marketing Inc.";
$subject = "Account Activation";
$message = wordwrap($msg,70) ;
$sender = "cjoveric#myalphaedge.com";
$mail_header="From: ".$name."<". $sender. ">\r\n";
$sendmail=mail($email, $subject,$message, $mail_header );
I was able to send an email, but my problem is I want to know if the user's email address exists in Yahoo, GMail or other mail services.
Is there any way I could filter out invalid emails?
Use SMTP mail the best and easy to use SMTP.
$mail->IsHTML(true);
$mail->From="admin#example.com";
$mail->FromName="Example.com";
$mail->Sender=$from; // indicates ReturnPath header
$mail->AddReplyTo($from, $from_name); // indicates ReplyTo headers
$mail->AddCC('cc#phpgang.com.com', 'CC: to phpgang.com');
$mail->Subject = $subject;
$mail->Body = $body;
$mail->AddAddress($to);
if(!$mail->Send())
{
$error = 'Mail error: '.$mail->ErrorInfo;
return true;
}
else
{
$error = 'Message sent!';
return false;
}
Not really. About the best you can do is send an email and see if the user responds to it.
Doing a regex check on email address can be frustrating for some users, depending on regex. So, I recommend to skip your regex test and just send the verification email with a confirmation link -- anything else will leave your application brittle and subject to breakage as soon as someone comes up with a new DNS or SMTP extension. It's best to get that dealt with when their paying attention.
For example:
-a confirmation code that needs to be filled in your website
-a link, going to your website, that needs to be visited
And still it is uncertain whether the email is existing afterwards, as it is easy to simply create a temporary email to pass the validation and delete it afterwards.
Instead of validating email addresses you can use the Google API to let your users sign in using their account. It is also possible to use OpenID on a similar way. Though, even this is not 100% perfect. But heay, nothing is 100%. We all try to make is work as we want as much as possible. That's it.
PS: ICANN is expected to approve UNICODE domain names Real Soon Now. That will play merry hell with Regex patterns for email addresses.
I'm getting this error when trying to send an email using swiftmailer and the sendgrid smtp
Fatal error: *Uncaught exception 'Swift_TransportException' with message 'Expected response code 250 but got code "", with message ""'*
Here's my code :
$hdr = new SmtpApiHeader();
// Set all of the above variables
$hdr->addTo($toList);
$hdr->addSubVal('-name-', $nameList);
$hdr->addSubVal('-time-', $timeList);
// Specify that this is an initial contact message
$hdr->setCategory("initial");
// The subject of your email
$subject = 'Example SendGrid Email';
// Where is this message coming from. For example, this message can be from
// support#yourcompany.com, info#yourcompany.com
$from = array('no-reply#mupiz.com' => 'Mupiz');
$to = array('antonin#noos.fr'=>'AN',"antonin#mupiz.com"=>"AN2s");
$text="Hello -name-
Thank you for your interest in our products. We have set up an appointment
to call you at -time- EST to discuss your needs in more detail.
Regards,
Fred, How are you?
";
$html = "
<html>
<head></head>
<body>
<p>Hello -name-,<br>
Thank you for your interest in our products. We have set up an appointment
to call you at -time- EST to discuss your needs in more detail.
Regards,
Fred, How are you?<br>
</p>
</body>
</html>
";
// Your SendGrid account credentials
$username = 'XXXX';
$password = 'XXXX';
// Create new swift connection and authenticate
$transport = Swift_SmtpTransport::newInstance('smtp.sendgrid.net', 25);
$transport ->setUsername($username);
$transport ->setPassword($password);
$swift = Swift_Mailer::newInstance($transport);
// Create a message (subject)
$message = new Swift_Message($subject);
// add SMTPAPI header to the message
// *****IMPORTANT NOTE*****
// SendGrid's asJSON function escapes characters. If you are using Swift Mailer's
// PHP Mailer functions, the getTextHeader function will also escape characters.
// This can cause the filter to be dropped.
$headers = $message->getHeaders();
$headers->addTextHeader('X-SMTPAPI', $hdr->asJSON());
// attach the body of the email
$message->setFrom($from);
$message->setBody($html, 'text/html');
$message->setTo($to);
$message->addPart($text, 'text/plain');
// send message
if ($recipients = $swift->send($message, $failures))
{
// This will let us know how many users received this message
// If we specify the names in the X-SMTPAPI header, then this will always be 1.
echo 'Message sent out to '.$recipients.' users';
}
// something went wrong =(
else
{
echo "Something went wrong - ";
print_r($failures);
}
An idea ?
Thanks
There could be a number of things causing this. The most likely one is that your server has connecting to external hosts turned off. Other possibilities are that you're using an old version of PHP that has an openSSL error or that you're being rate limited by something.
You should take a look at this question for details on the external host issue: send mails via sendgrid
On a separate note, you should use the SendGrid PHP library if you want to send emails using SendGrid. It addresses a whole bunch of subtle nuances with Swift and sending in general. Also, it gives you access to the HTTP API in case you can't use SMTP for whatever reason.
https://github.com/sendgrid/sendgrid-php
Full Disclosure: I work as a developer evangelist for SendGrid and work on the PHP library from time to time.
for sendgrid might be two resons:
you may have the authentification data wrong
your account might still be provisioned, so you must wait a bit for it to be fully activated
so
check all the autentification data from app/config/mail.php to match with the data from https://sendgrid.com/docs/Integrate/index.html
check also not the have a top message/notification on your sendgrid account like:
Your account is still being provisioned, you may not be able to send
emails.
You will also receive this error if your account is frozen for billing reasons (e.g. lapsed credit card expiry date).
Note: SendGrid doesn't drop the message(s), they hold them until your billing issue is resolved then process them even when this error is returned.