PHPMailer don't send mail with attached zip file - php

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.

Related

Unable to send email using PHPMailer and CRON job

I am experiencing an issue automating the sending of emails using PHPMailer and a cron job. I am using a shared hosting server and CPanel. I have tested my PHPmailer installation and have been able to successfully send a basic email by running the below script in the browser.
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
/* Exception class. */
require '/home/eepherg/public_html/mobiq1.2/lib/PHPMailer-master/src/Exception.php';
/* The main PHPMailer class. */
require '/home/eepherg/public_html/mobiq1.2/lib/PHPMailer-master/src/PHPMailer.php';
/* SMTP class, needed if you want to use SMTP. */
require '/home/eepherg/public_html/mobiq1.2/lib/PHPMailer-master/src/SMTP.php';
/* Create a new PHPMailer object. Passing TRUE to the constructor enables exceptions. */
$mail = new PHPMailer(TRUE);
/* Set the mail sender. */
$mail->setFrom('darth#empire.com', 'Darth Vader');
/* Add a recipient. */
$mail->addAddress('test#provision.com', 'Emperor');
/* Set the subject. */
$mail->Subject = 'Force';
/* Set the mail message body. */
$mail->Body = 'There is a great disturbance in the Force.';
/* Finally send the mail. */
$mail->send();
?>
I have setup a CRON job as per the below to run once a day ...
12 00 * * * /usr/local/bin/php /home/eepherg/public_html/mobiq1.2/test.php
This CRON job runs without any errors, however no email is received. Is there perhaps an issue with my references or does anyone have any ideas why the script will work when run in the browser but not when run using the CRON job?
The reason you can't see whats going wrong is because you have no error handling at all. Look at the examples provided with PHPMailer to see how to detect and report send errors - this will give you some idea of what's going on:
if (!$mail->send()) {
echo 'Mailer Error: '. $mail->ErrorInfo;
} else {
echo 'Message sent!';
}
You can also try enabling debug output:
$mail->SMTPDebug = 3;
Because this all happens during a cron run, it may not be obvious where the output goes, but you can configure cron to email any output (normal error-free scripts should produce no output) to you. To do that, just put your email address in an environment variable inside your cron file:
MAILTO=me#example.com
With that set, you should receive any output that cron generates.

phpmailer can not send email

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.

Sending a mail with php: Script is waiting for the answer?

I am using the class PHPMailer to send Mails via SMTP:
<?php
require 'php_mailer/class.phpmailer.php';
$mail = new PHPMailer;
$mail->IsSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.dfgdfgdfg.de'; // Specify main and backup server
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'dfgdfg'; // SMTP username
$mail->Password = 'dfgsdfgdsfg'; // SMTP password
//$mail->SMTPSecure = 'tls'; // Enable encryption, 'ssl' also accepted
$mail->From = 'community#fdgdfg.de';
$mail->FromName = 'dfgdfgdg';
$mail->AddAddress('interview#dfgdfg.de', 'Udo'); // Add a recipient
$mail->AddBCC('bcc#example.com');
$mail->WordWrap = 50; // Set word wrap to 50 characters
$mail->IsHTML(true); // Set email format to HTML
$mail->Subject = 'HTML-Mail mit Logo';
$mail->Body = 'Nachfolgend das <b>Logo</b>';
$mail->AltBody = 'Aktiviere HTML, damit das Logo angezeigt wird';
if(!$mail->Send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
exit;
}
?>
My Questions:
Whats the best way to send to a lot of Mails (same Mailtext, only the appellation is different (Hello $NAME)?
Is the PHP script waiting until every mail is delivered? Because sometimes I want to send a mail to some hundreds people, when a user is doing an action on the website. so this user cant wait of course, until all those mail were sent succesful!
Thanks!
Alex
You are setting PHPMailer to interact with SMTP, so I guess that it will wait for it to complete. This is not optimal, because as you say you will block the PHP script until SMTP responds.
It would be better to send through your localhost: set PHPMailer to use sendmail, which will usually be a wrapper to a local exim4 or postfix, which will then handle the mailing for you. This is much better, also because the local server will handle any possible temporary error, and retry later. PHP won't.
You may also want to explore other options, like Mandrill or Sendgrid to do the job, especially if you do lot of mailing or bulk mailing.
Whats the best way to send to a lot of Mails (same Mailtext, only the
appellation is different (Hello $NAME)?
You can do something like, Set the name too.
// rest of code first
$mail->AddAddress("you#example.com")
$ids = mysql_query($select, $connection) or die(mysql_error());
while ($row = mysql_fetch_row($ids)) {
$mail->AddBCC($row[0]);
}
$mail->Send();//Sends the email
You can have special string 'name_here' in the body and place $name with str_replace function
Is the PHP script waiting until every mail is delivered? Because sometimes I want to send a mail to some hundreds people, when a user is doing an action on the website. so this user cant wait of course, until all those mail were sent succesful!
Yes according to my knowledge you will have to wait.
How to do a str_replace ? Assume that your email body is as follows
$body = " Dear %first_name%,
other stuff goes here....... ";
$body = str_replace("%first_name%", $first_name, $body);
above will replace %first_name% with the name($first_name) you provide.

send email from localhost to external email account

if(mysql_affected_rows()==1)
{
$msg="To activate your account, please click on the following link:\n\n
http://localhost:80/activate.php?email=".urlencode($email)."&key=".$activation;
if(mail($email,"Registration Confirmation", $msg, "From: myemail#mycompany.com\r\nX-
Mailer: php"))
{
echo '<div> Thank you for registering. A confirmation email has been sent to '.
$email.'.Please click on the link to activate your account then</div>';
}
}
I use that code snippet to send an email from myemail#mycomapany.com to $email (myyahoo#yahoo.com) but I fail to receive any email in the yahoo account. I have got the echoed message displayed in the browser to indicate the successful mailing, though. Also, I have tried sending an email from myemail#mycomapany.com to the yahoo account directly via Outlook and it works fine. Would someone please help me fix that source snip or any kind of extra settings to make the mail function work ? Thank you so much.
EDIT: By the way, I also set up my php.ini's stmp script block as follows,
[mail function]
; For Win32 only.
; http://php.net/smtp
SMTP = mail.mycompany.com
; http://php.net/smtp-port
smtp_port = 25
; For Win32 only.
; http://php.net/sendmail-from
sendmail_from = postmaster#localhost
My problem is to set my local computer as a local mail server, and i editted php.ini as above but it still doesn't work.
[RESOLVED]
<?php
function SendMail($from, $to, $subject, $body)
{
require("class.phpmailer.php");
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->Host = "mail.mycompany.com";
$mail->SMTPAuth = true;
$mail->Username = "My name"; // SMTP username
$mail->Password = "mypassword"; // SMTP password = one used in Outlook
$mail->From = "myemail#mycompany.com";
$mail->FromName = "Registration Confirmation Email";
$mail->AddAddress($to);
$mail->IsHTML(true); // set email format to HTML
$mail->Subject = $subject;
$mail->Body = $body;
if(!$mail->Send())
{
echo "Message could not be sent. <p>";
echo "Mailer Error: " . $mail->ErrorInfo;
return false;
}
return true;
}
?>
I include the above code snip to demonstrate a small but working example that uses phpmailer. Thanks to the one who introduces it to me in the post below.
Take a look at phpMailer it's good and very easy to use, and you can send email-s from your existing email accounts (like gmail)
Try this one, from this script you can also send email from your local file to external email.
require_once('class.phpmailer.php');
define('SMTPSERVER', 'mail.yourcompany.com');// sec. smtp server
define('SMTPUSER', 'info#yourcompanyname.com'); // sec. smtp username
define('SMTPPWD', '123456'); // sec. password
$useremail = 'mail#mail.com';
$msg = 'your text here';
$from = 'info#yourcompanyname.com';
$mailTest=new EmailService();
if ($mailTest->generalMailer($useremail, $from, 'Yoursite.com', 'Your company name', $msg)) {
} else {
if (!$mailTest->generalMailer($useremail, $from, 'Yoursite.com', 'Your company name', $msg)) {
if (!empty($error)) echo $error;
} else {
echo 'Yep, the message is send (after hard working)';
}
}
header("location:index.php?email_msg=Email sent successfully");
You should look into mail headers. Most of the time the reason is either:
Skipped Reply to/From headers
Skipped X-Mailer
For further details, please see here.
Edit
Ok, I think I know where the problem might be.
There is quite a big difference between LAMP and WAMP. Linux systems tend to have the sendmail library, which allows you to send mail to other systems without configuring anything. Windows does not.
Therefore, you should have an SMTP server installed, in order to send mail to outer sources. Take a look at this question for details.
Also, if you have a need to test this, you should take a look at Papercut, which is indispensable while testing your system.
If you can send a plain mail(), you should be able to send a mail from a library too. Not the opposite way around. Only exception is, if you use an already existing SMTP/IMAP server to do this, e.g. Gmail.
Are you sure that you have an MTA (Mail Transport Agent = Mailserver) installed on your local machine? Otherwise, you'll need to use your ISP's SMTP server instead.
Mostly that will be mail.yourprovider.com or smtp.yourprovider.com (the same hostname as what you use for outgoing mail in Outlook). PHP cannot mail by itself, it needs an MTA (either locally or remote) to do so.

Sent mails with phpmailer don't go to "Sent" IMAP folder

in my CRM online system I control ingoing mails with IMAP protocol.
Now I'm making sending mails with phpmailer and SMTP protocol.
Everything is ok but I have one wierd thing. How to make sent with phpmailer script mails go to "Sent" IMAP folder?
There is now a method getSentMIMEMessage in PHPMailer which returns the whole MIME string
$mail = new PHPMailer();
//code to handle phpmailer
$result = $mail->Send();
if ($result) {
$mail_string = $mail->getSentMIMEMessage();
imap_append($ImapStream, $folder, $mail_string, "\\Seen");
}
I found easier way to do this.
PHPmailer prepares email as string - all You have to do is to put it into right IMAP folder.
I expanded phpmailer class with this code (since vars are protected I can't reach them):
class PHPMailer_mine extends PHPMailer {
public function get_mail_string() {
return $this->MIMEHeader.$this->MIMEBody;
}}
PHP code:
$mail= new PHPMailer_mine();
//code to handle phpmailer
$result=$mail->Send();
if ($result) {
$mail_string=$mail->get_mail_string();
imap_append($ImapStream, $folder, $mail_string, "\\Seen");
}
It works well.
Well, it's pretty difficult, but can be done.
Take a look at the imap-append function.
By being connected to an IMAP stream resource, you can use the imap-append() to append your mails to the Sent folder of your IMAP account.
But reading through the comments will show you that it's a bit tedious to accomplish, but certainly not impossible - you'll probably need to code something on your own, since phpmailer doesn't support this out of the box (and will most likely be too time consuming to implement instead of making something yourself).
You need to be relaying your sent mail through the IMAP host
The IMAP host needs to support the feature (which very few do)
If either of these two points are not true, the short answer is "You can't". In short, really it's down to the mail provider, not your code.
As much as I hate M$, Exchange is one place where they really have got things right - if you are using an Exchange server, all of this is handled for you.
This works well :
Php Manual
if (!$mail->send()) {
//echo "Mailer Error: " . $mail->ErrorInfo;
} else{
//echo "Message sent!";
//Section 2: IMAP
//Uncomment these to save your message in the 'Sent Mail' folder.
if (save_mail($mail)) {
echo "Message saved!";
}
}
//function
function save_mail($mail)
{
$providerMail = 'Gmail';
$providerMailSentFolder = 'Sent Mail';//You can change 'Sent Mail' to any folder
$providerMailImap = 'imap.gmail.com';//imap.one.com
$path = "{".$providerMailImap.":993/imap/ssl}[".$providerMail."]/".$providerMailSentFolder;
//Tell your server to open an IMAP connection
//using the same username and password as you used for SMTP
$imapStream = imap_open($path, $mail->Username, $mail->Password);
$result = imap_append($imapStream, $path, $mail->getSentMIMEMessage());
imap_close($imapStream);
}

Categories