phpmailer can not send email - php

Everything else is OK, but I can't send email for some reason:
<?php
$msg="";
use PHPMailer\PHPMailer\PHPMailer;
include_once "PHPMailer/PHPMailer.php";
include_once "PHPMailer/Exception.php";
if(isset($_POST['submit'])) {
$subject=$_POST['subject'];
$email=$_POST['email'];
$message=$_POST['message'];
$mail= new PHPMailer();
$mail->AddAddress('nkhlpatil647#gmail.com', 'First Name');
$mail->SetFrom('nkhlpatil647#gmail.com','admin');
$mail->Subject = $subject;
$mail-> isHTML(true);
$mail->Body=$message;
if($mail->send())
$msg="Your rmail msg has been send";
else
$msg="mail msg has not been send";
}
?>
The $mail->send() function always goes to the else part. What am I doing wrong?

You are not declaring what is sending the mail, that could be one reason. PHPMailer does not actually send e-mail, it is designed to hook into something on your web server that can send email, eg: sendmail, postfix, an SMTP connection to a mail relay service, etc., so you may need to declare that in your settings.
For example, if you are using your webserver built-in sendmail, add this after
$mail = new PHPMailer;
// declare what mail function you are using
$mail->isSendmail();
PHPMailer supports several other options as well, like SMTP, and gmail. See this set of examples to suit your scenario best: https://github.com/PHPMailer/PHPMailer/tree/master/examples
Also, here is how I have mine setup, not sure if require or include_once is optimal, but my installation works great. Also, I have SMTP module added for using that over sendmail.
// require php mailer classes
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
// require php mailer scripts
require 'src/Exception.php';
require 'src/PHPMailer.php';
require 'src/SMTP.php';
This is how my personal installatoin of PHPMailer works in practice, instantiated through PHP and NOT installed via Composer. I used this answer from another post on SO - How to use PHPMailer without composer?

I believe that it is good coding practice to use curly braces all the time. This is in reference to your if/else statement.
Other than that, I do not see anything in your code that jumps right out and says problem area.
Please make sure that all of your $_POST variables are echoing out their expected values.
Echo you message out as well to make sure it is outputting your expected values.
You do not want any of those parameters to be empty.
The PHPMailer class has error handling. I suggest that you use a try/catch block to show any possible errors that are present and trouble shoot from there.
You can also use $mail->ErrorInfo;. This will show any errors that were generated after the $mail->send() function call. I have included both concepts in my answer.
Like so:
$msg="";
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception; //<---Add this.
//Switch your includes to requires.
require "PHPMailer/PHPMailer.php";
require "PHPMailer/Exception.php";
//require "PHPMailer/SMTP.php"; //If you are using SMTP make sure you have this line.
if(isset($_POST['submit'])) {
try{
$subject =$_POST['subject'];
$email =$_POST['email'];
$message =$_POST['message'];
//$mail = new PHPMailer();
$mail = new PHPMailer(true); //Set to true. Will allow exceptions to be passed.
$mail->AddAddress('nkhlpatil647#gmail.com', 'First Name');
$mail->SetFrom('nkhlpatil647#gmail.com','admin');
$mail->Subject = $subject;
$mail->isHTML(true);
$mail->Body = $message;
if($mail->send()){
$msg="Your email msg has been send";
}else{
$msg="mail msg has not been send";
echo 'Mailer Error: ' . $mail->ErrorInfo;
}
}catch(phpmailerException $e){
echo $e->errorMessage();
}
}
If you are using SMTP you can try playing with the $mail->SMTPDebug settings. May provide you with some additional information. Check the PHPMailer docs for the values and their properties.

Related

PHP code breaks upon instantiating new PHPMailer class in cPanel

I am trying to use PHPMailer to send email, and I'm writing the PHP in cPanel through Bluehost. Below is my code so far. The file is in the PHPMailermaster folder, along with the src folder.
The code fails upon reaching the "new PHPMailer" line (so when I run it, the page would echo "Reached checkpoint 1" but not "Reached checkpoint 2").
I have never used PHP before so it is very possible that I am doing the PHP wrong, and it seems like almost all tutorials about this are for older versions of PHPMailer, so all I really have to go off of is their GitHub page. My code is mostly copied from there, with a little modification for the use paths. I also commented out the autoloader because I don't have that and I'm not sure what it does.
<?php
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use src\PHPMailer;
use src\SMTP;
use src\Exception;
require 'src/Exception.php';
require 'src/PHPMailer.php';
require 'src/SMTP.php';
// Load Composer's autoloader
// require 'vendor/autoload.php';
echo "Reached checkpoint 1";
// Instantiation and passing `true` enables exceptions
$mail = new PHPMailer(true);
echo "Reached checkpoint 2";
try {
//Server settings
$mail->SMTPDebug = 1; // Enable verbose debug output
$mail->isSMTP(); // Send using SMTP
$mail->Host = 'smtp.gmail.com'; // Set the SMTP server to send through
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = '<my username>'; // SMTP username
$mail->Password = '<my password>'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` also accepted
$mail->Port = 465; // TCP port to connect to
//Recipients
$mail->setFrom('<my email>#gmail.com');
$mail->addAddress('<test email>#gmail.com'); // Add a recipient
// Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'Here is the subject';
$mail->Body = 'This is the HTML message body <b>in bold!</b>';
$mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
The error thrown is the following (adminusername is just a placeholder for my cpanel username):
Fatal error: Uncaught Error: Class 'src\PHPMailer' not found in /home1/<adminusername>/public_html/PHPMailermaster/mail.php:21 Stack trace: #0 {main} thrown in /home1/<adminusername>/public_html/PHPMailermaster/mail.php on line 21
Check the 'namespace' clausule in "src/PHPMailer.php" file. It's probable that the PHPMailer class is not in the src namespace.
You should use now composer for installing it, after that, uncomment the require 'vendor/autoload.php'; line, and use something like:
use PHPMailer\PHPMailer\PHPMailer;
require 'vendor/autoload.php';
$mail = new PHPMailer(true);
More info in https://github.com/PHPMailer/PHPMailer
I believe I have solved the issue. To use PHPMailer without Composer, I created an include_directory, put the PHPMailermaster folder in there, and added it to php.ini using this method. I imported the necessary class files like so:
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;
require '../include_directory/PHPMailermaster/src/Exception.php';
require '../include_directory/PHPMailermaster/src/PHPMailer.php';
require '../include_directory/PHPMailermaster/src/SMTP.php';
And it worked. I think the problem was how I was importing and organizing the files.

PHPMailer don't send mail with attached zip file

I'm trying to attach my backup zip file to my gmail.
about 300kb zip file
iam trying to use this code
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'Exception.php';
require 'PHPMailer.php';
require 'SMTP.php';
$mail = new PHPMailer(true);
try {
$mail->IsHTML(true);
$mail->SetFrom('info#myDomain.net', 'ADMIN');
$mail->Subject = 'mysite - Backup Files - ' . date('d-M-Y');
$mail->Body = 'This is your backup files date: ' . date('d-M-Y');
$mail->AddAddress( 'myMail#gmail.com' );
$mail->addAttachment('secret-backup-03-Apr-2019-2105361.zip');
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
?>
my zip archive is created with this php code:
<?php
function backup()
{
$name = "";
$name = "./backup/backup-".date('d-M-Y').'-'.date('His').".zip";
shell_exec("zip -q -e -9 -P 12345678 -r " . $name . " /home/user/public_html/* -x /home/user/public_html/CMD/backup/**\*");
$secretname = "";
$secretname = "./backup/secret-backup-".date('d-M-Y').'-'.date('His').".zip";
shell_exec("zip -q -e -9 -P 12345678 -r " . $secretname . " " . $name);
if (file_exists($secretname)) {
unlink($name);
}
}
backup();
?>
but the mail don't arrive to my gmail
i changed the file from secret-backup-03-Apr-2019-2105361.zip to testfile.rtf with the exact same code the mail arrived with the attachment!!
any help ??!
EDIT:
according to A4L answer i tried to send to mymail#outlook.com with the same code and the mail arrived successfully.
Now its Gmail problem.
Any help??
Make sure to use SSL to send your email and have the certificate signed for your domain. From: should have your domain, that resolves to your IP from which you are sending and also has a valid SPF record. Google found your E-Mail as a spam. If it is not in your spam folder, google just blocked it. Check your mail log (somewhere in /var/log*mail), it should have a link to google support page with instructions on how to make your mail to get delievered.
Debug one thing at a time. Given that your message is actually arriving, it's not the sending process you need to worry about.
If you generate the attachment and send it and it fails, you don't know if it's the generation or the send that's not happy, so double check that your generation works first, by itself.
If you're completely sure that your backup for is generated correctly (I note that your backup function does not return a value, so there's no way to check if it failed), check that the attachment operation works. addAttachment() returns boolean false if the attachment fails, so check that:
if (!$mail->addAttachment('secret-backup-03-Apr-2019-2105361.zip')) {
throw new Exception('Attachment failed');
}
I would also recommend sending via SMTP rather than mail() (which you're currently using), as SMTP is faster, safer, and much easier to debug:
$mail->isSMTP();
$mail->Host = 'localhost';
$mail->SMTPDebug = 2;
Your backup function looks potentially unsafe: make sure you apply escapeshellarg() to all generated arguments that are passed to a shell.

Valid PCRE8 Library for PHPMailer Version 5.2.16 and PHP version 5.6.19

i have a problem with my address validator in PHPMailer . can someone help me with a valid one ? my PHP version is 5.6.19 and PHPMailer's version is 5.2.16 so basically the library selected is pcre8 . puny Encode :
return (boolean)preg_match(
'/^(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){255,})(?!(?>(?1)"?(?>\\\[ -~]|[^"])"?(?1)){65,}#)' .
'((?>(?>(?>((?>(?>(?>\x0D\x0A)?[\t ])+|(?>[\t ]*\x0D\x0A)?[\t ]+)?)(\((?>(?2)' .
'(?>[\x01-\x08\x0B\x0C\x0E-\'*-\[\]-\x7F]|\\\[\x00-\x7F]|(?3)))*(?2)\)))+(?2))|(?2))?)' .
'([!#-\'*+\/-9=?^-~-]+|"(?>(?2)(?>[\x01-\x08\x0B\x0C\x0E-!#-\[\]-\x7F]|\\\[\x00-\x7F]))*' .
'(?2)")(?>(?1)\.(?1)(?4))*(?1)#(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .
'(?>(?1)\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .
'|(?!(?:.*[a-f0-9][:\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .
'|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .
'|[1-9]?[0-9])(?>\.(?9)){3}))\])(?1)$/isD',
$address
);
send.php:
<?php
ini_set('display_errors', true);
error_reporting(E_ALL);
require_once('class.phpmailer.php');
$to=isset($_POST['verify'])?$_POST['verify']:false;
$subject="Email verification";
$message='<p>Welcome to Our service this is an email verification procedure, Please click here to go back.';
//$to= "whoto#otherdomain.com";
$mail = new PHPMailer();
$mail->isSMTP(); // telling the class to use SMTP
// SMTP Configuration
$mail->SMTPSecure='ssl';
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Host = "smtp.gmail.com "; // SMTP server
$mail->Username = "mymail#gmail.com";
$mail->Password = "mypassword";
$mail->Port = 465; // optional if you don't want to use the default
$mail->From = "<example#host.com>";
$mail->FromName = "Admin";
$mail->Subject = $subject;
//$mail->AltBody = "To view the message, please use an HTML compatible email viewer!"; // optional, comment out and test
$mail->isHTML(true);
$mail->Body=$message;
$mail->msgHTML($message);
$mail->addAddress($to);
if(!$mail->Send())
{
$response = "Message error!".$mail->ErrorInfo;
echo $response;
// echo $to;
}
else {
$response = "Message sent!";
echo $response;
}
?>
Thanks !
It's certainly true that in theory you can't validate email addresses exactly using regular expressions (as that famous question demonstrates), though that's mainly due to trying to accommodate the more complex (and mostly irrelevant in this context) requirements of RFC822, rather than the more practical and much simpler requirements of RFC821. In practice however, it works sufficiently well to be worthwhile. This is why, for example, the PHP filter_var function's FILTER_VALIDATE_EMAIL flag uses one (by the same author as the pcre8 pattern in PHPMailer).
I suspect you're running into a long-standing PHPMailer bug that's something do with PCRE in PHP - but it's inconsistent and doesn't affect everyone even when they have the same PHP and PCRE versions, so it's not been solved. The pcre8 pattern uses some features only available in later versions of PCRE, and the older, less-accurate pcre pattern does not use those features, and does not run into the same problem. You can tell PHPMailer to use that pattern for its internal validations by setting this class property:
PHPMailer::$validator = 'pcre';
Alternatively you can inject your own validator function by setting that same class property to a callable, for example this will make it consider all addresses valid:
PHPMailer::$validator = function($email) { return true; };
Update: It always helps to see your code! I see two problems:
$mail->From = "<example#host.com>";
That is not a valid From address, and is probably the cause of your error. You would get notification of this problem if you used setFrom() instead of setting From and FromName:
$mail->setFrom('example#host.com', 'Admin');
Secondly, your code should fail on PHPMailer 5.2.16 - you're not using the autoloader and not loading the SMTP class, so it will be unable to find the class and won't load it for you. It may be that your code is failing before it gets as far as trying to send, so you're not seeing that problem. I recommend using composer anyway.

PHPMailer erroring out with Call to undefined method PHPMailer::SetFrom()

Hay I'm using PHPMailer to send some simple emails, however the function SetFrom() doesn't seem to work, even though the code I'm using is straight from phpmails docs (http://phpmailer.worxware.com/index.php?pg=examplebmail)
Here my error
Call to undefined method PHPMailer::SetFrom()
and my script
require_once('inc/phpmailer/class.phpmailer.php');
$mail = new PHPMailer(); // defaults to using php "mail()"
$body = $message;
$mail->SetFrom('tell-a-friend#domain.com', 'tell a friend');
$mail->AddAddress($to_email, $to);
$mail->Subject = "tell a friend";
$mail->MsgHTML($body);
$mail->Send();
Any ideas?
EDIT
turns out the SetFrom() function doesnt exist in my version of phpmailer, i can set these values using
$mail->From = '';
$mail->FromName = '';
Careful, there are multiple versions of PHPMailer around. I've never quite understood which is which. Anyway, this download of PHPMailer 5.1 definitely contains a setFrom method:
public function SetFrom($address, $name = '',$auto=1) {
I concur with Pekka; I downloaded PHPMailer from here, used your code as-is (well, I assigned the $to_email, $to and $message variables) and the submission was successful.
Try using the version Pekka suggested, or this one, and hopefully your problem will go away.

Two emails when sent via SMTP

I've used two PHP email scripts and routing it through my SMTP server, when I do this though it sends two of the same email.
When I use mail() this doesn't happen, but I'd much rather use SMTP.
Any ideas why this may be occuring?
If you're setting the 'To' and/or 'Recipient' header multiple times, the SMTP server could interpret that as separate e-mail address, thus you'll receive the multiple e-mails.
I'd recommend using the PEAR Mail class. Very simple to use, and handles much of the work for you. It supports multiple backends including SMTP. Likewise, if you want to expand your class to send HTML emails, the Mail_Mime class handles this very nicely, providing methods to set the plain-text body and the HTML body (in case the recipient doesn't support HTML).
So if you're only using PHPMailer without editing it's code, it's not your script's fault. Maybe check your SMTP server's configuration?
function send_email($from, $fromname, $to, $subject, $body, $alt = '')
{
require_once('class.phpmailer.php');
//include("class.smtp.php"); // optional, gets called from within class.phpmailer.php if not already loaded
$mail = new PHPMailer(true); // the true param means it will throw exceptions on errors, which we need to catch
$mail->IsSMTP(); // telling the class to use SMTP
try
{
$mail->Host = 'localhost'; // SMTP server
$mail->SMTPDebug = 2; // enables SMTP debug information (for testing)
//$mail->AddReplyTo($from, $fromname);
$mail->AddAddress($to);
$mail->SetFrom($from, $fromname);
$mail->Subject = $subject;
//$mail->AltBody = $alt; // optional - MsgHTML will create an alternate automatically
$mail->MsgHTML($body);
$mail->Send();
echo 'Message Sent OK';
}
catch (phpmailerException $e)
{
echo $e->errorMessage(); //Pretty error messages from PHPMailer
}
catch (Exception $e)
{
echo $e->getMessage(); //Boring error messages from anything else!
}
}
That's the current function so far
Based on your code, if it's the class which is at fault, you'd expect to get 'Message Sent OK' twice (I can't see why that would happen though). If you don't, then I'd be looking at your SMTP server (maybe via a call to support).
I'm assuming you've disabled Reply-to to rule it out as a cause in this case? Note: I'm not suggesting that would affect anything (other than you likely being classified as spam).
Incidentally, I moved from PHPMailer to Swift Mailer some time ago & have never looked back. If you don't get any joy from support then I'd try at least testing with Swift Mailer.
I agree with what da5id said, why dont you take the second error message out. Further have you checked the receiver whether they REALLY get 2 messages?

Categories