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.
Related
I keep getting error when trying to send email using PHP mailer (localhost). or does php mailer not work on localhost?
<?php
//Import PHPMailer classes into the global namespace
//These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
require 'src/Exception.php';
require 'src/PHPMailer.php';
require 'src/SMTP.php';
//Load Composer's autoloader
require 'vendor/autoload.php';
//Create an instance; passing `true` enables exceptions
$mail = new PHPMailer(true);
try {
//Server settings
$mail->SMTPDebug = SMTP::DEBUG_SERVER; //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 = 'default#gmail.com'; //SMTP username
$mail->Password = '00000120'; //SMTP password
// $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS; //Enable implicit TLS encryption
$mail->Port = 465; //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
//Recipients
$mail->setFrom('NatsuDragneelxd42069#gmail.com', 'Mailer');
$mail->addAddress('Received#gmail.com', 'Joe User'); //Add a recipient
//$mail->addAddress('ellen#example.com'); //Name is optional
$mail->addReplyTo('Noreply#gmail.com', 'Info');
// $mail->addCC('cc#example.com');
// $mail->addBCC('bcc#example.com');
//Attachments
// $mail->addAttachment('/var/tmp/file.tar.gz'); //Add attachments
// $mail->addAttachment('/tmp/image.jpg', 'new.jpg'); //Optional name
//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}";
}
This is the error that I get:
SERVER -> CLIENT:
SMTP Error: Could not connect to SMTP host.
Message could not be sent. Mailer Error: SMTP Error: Could not connect to SMTP host.
I don't know why you commented out this line, but it will make the connection fail because it will attempt to make an unencrypted connection to a port expecting encryption:
// $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
Uncomment that and you might have more luck. You also might want to try setting SMTPDebug = SMTP::DEBUG_CONNECTION as it will give you more info about the TLS phase of the connection.
This may not solve your whole problem because Gmail no longer (as of May 2022) allows authentication using regular ID and password. You need to either switch to using XOAUTH2 (which PHPMailer supports), or create an App Password in your gmail console.
Also note that gmail won't let you use arbitrary from addresses, only your Username address and predefined aliases.
All this is covered in the PHPMailer troubleshooting guide.
all I need to do was fix the less secured but since it's been removed by google itself I search for an alternative less secure apps alternative
I am facing some pain trying to install another one php library without composer and other stuff.
What did I do:
In the same folder where executable script (index.php) is situated I created folder fpdf;
In fpdf created folder lib and unziped there all from https://github.com/swiftmailer/swiftmailer/tree/master/lib ;
In lib created folders Doctrine and EmailValidator and unziped there stuff from https://github.com/doctrine/lexer and https://github.com/egulias/EmailValidator respectively;
In the end of swift_required.php file I added code from this answer https://stackoverflow.com/a/50105900/15749307.
Getting error:
Parse error: syntax error, unexpected '?' in /home/virtwww/w_imaimachi_0f858928/http/fpdf/lib/EmailValidator/Validation/MessageIDValidation.php on line 47
line 47: public function getError() : ?InvalidEmail;
I have PHP 7 i guess.
If this nightmare can be end, please tell me how. If there is other library for sending email (I need to send a pdf as a string but not a file) that may easy to install without composer or another framework, or if there another non-third-party solution, please tell me.
It is not answer on the exact question but this is the code fro sending pdf through smtp that worked for me
Download "mailer" (only few php file) and extract to some folder on server https://github.com/PHPMailer/PHPMailer.
In your executable php file (index.php or whatever) add code:
Code (if I paste right after list above the syntax highlighting breaks for some reason):
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'path/to/src/Exception.php';
require 'path/tp/src/PHPMailer.php';
require 'path/to/src/SMTP.php';
And the code that will send pdf as binary string (not base64!):
function mail_attachment($pdf)
{
$mail = new PHPMailer();
// Settings
$mail->IsSMTP();
$mail->CharSet = 'UTF-8';
$mail->Host = "smtp.server.ua"; // SMTP server example
$mail->SMTPDebug = 0; // enables SMTP debug information (for testing)
$mail->SMTPAuth = true; // enable SMTP authentication
$mail->Port = 25; // set the SMTP port for the GMAIL server
$mail->Username = "login"; // SMTP account username example
$mail->Password = "passwrod"; // SMTP account password example
$mail->setFrom('aga#ugu.com', 'Mailer');
//$mail->addAddress('joe#example.net', 'Joe User'); //Add a recipient
$mail->addAddress('okumaima#outlook.com');
// 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->AddStringAttachment($pdf, 'file.pdf'); // not base64 !
echo $mail->send();
}
Should work, hope it will help someone.
I've done some searching before this post and I still can't seem to get this to work. I'm trying to setup a cron job with PHPMailer to send out an email every so often. The script below does work if I run it manually but does not work in the cron job scheduler.
For this example - I set it to run every minute. I'm thinking it has to do something with the "vendor/autoload.php" and it's path not loading correctly? I didn't add my SMTP credentials with api key for security reasons as well as recipients for this post.
Here is my cron job setup in Cpanel.
Here is my PHPMailer code:
// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
// Load Composer's autoloader
require 'vendor/autoload.php';
// Instantiation and passing `true` enables exceptions
$mail = new PHPMailer(true);
try {
// Server settings
// $mail->SMTPDebug = SMTP::DEBUG_SERVER; // Enable verbose debug output
$mail->isSMTP(); // Send using SMTP
$mail->Host = ''; // Set the SMTP server to send through
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = ''; // SMTP username
$mail->Password = ''; // SMTP password
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` also accepted
$mail->Port = 587; // TCP port to connect to
// Recipients
$mail->setFrom('email#email.com', '');
$mail->addAddress('email#email.com', ''); // Add a recipient
$mail->addReplyTo('email#email.com', '');
// $mail->addCC('cc#example.com');
// $mail->addBCC('');
// Content
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = 'PHPMailer email';
// $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->msgHTML(file_get_contents('email.html'), __DIR__); // Use this if not using the above code
// ********* PHP-MAILER ********* //
$mail->send();
echo 'Email sent!';
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
If anyone could help me, I would really appreciate it!
Can you share you error-message with us? I assume this will help a lot to find the issue.
I've shared my insights how to enable logging in a different post on stack overflow (see link below). This will explain how you can display errors in your cron execution:
https://stackoverflow.com/a/60250715/12880865
Please let me know if this helps you. If you'll get a proper error message, please share it with us so we can dig further into your question.
Fixed!
I had to use (dirname(DIR) which is the directory of the file.
I Changed:
require 'vendor/autoload.php';
to:
require (dirname(__DIR__).'/mailer/vendor/autoload.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.
Fatal error: Class 'PHPMailer' not found in C:\wamp\www\sendemail.php on line 13
This is line 13:
$mail = new PHPMailer();
I have already researched and they say you need to have these:
require_once('class.pop3.php');
require_once('class.phpmailer.php');
require_once('class.smtp.php');
require_once('PHPMailerAutoload.php');
But I already have those and they reside in the same folder as sendemail.php but still the same error.
<?php
/**
* This example shows settings to use when sending via Google's Gmail servers.
*/
//SMTP needs accurate times, and the PHP time zone MUST be set
//This should be done in your php.ini, but this is how to do it if you don't have access to that
date_default_timezone_set('Etc/UTC');
require_once('class.pop3.php');
require_once('class.phpmailer.php');
require_once('class.smtp.php');
require_once('PHPMailerAutoload.php');
//Create a new PHPMailer instance
$mail = new PHPMailer;
//Tell PHPMailer to use SMTP
$mail->isSMTP();
//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug = 2;
//Ask for HTML-friendly debug output
$mail->Debugoutput = 'html';
//Set the hostname of the mail server
$mail->Host = 'smtp.gmail.com';
// use
// $mail->Host = gethostbyname('smtp.gmail.com');
// if your network does not support SMTP over IPv6
//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission
$mail->Port = 587;
//Set the encryption system to use - ssl (deprecated) or tls
$mail->SMTPSecure = 'tls';
//Whether to use SMTP authentication
$mail->SMTPAuth = true;
//Username to use for SMTP authentication - use full email address for gmail
$mail->Username = "email#email.com";
//Password to use for SMTP authentication
$mail->Password = "password";
//Set who the message is to be sent from
$mail->setFrom('email#email.com', 'name');
//Set an alternative reply-to address
//$mail->addReplyTo('replyto#example.com', 'First Last');
//Set who the message is to be sent to
$mail->addAddress('email#sample.com', 'name');
//Set the subject line
$mail->Subject = 'PHPMailer GMail SMTP test';
//Read an HTML message body from an external file, convert referenced images to embedded,
//convert HTML into a basic plain-text alternative body
$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));
//Replace the plain text body with one created manually
$mail->AltBody = 'This is a plain-text message body';
//Attach an image file
//$mail->addAttachment('images/phpmailer_mini.png');
//send the message, check for errors
if (!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}
Here is my file layout:
I encountered the same issue, and managed to solve it by entering the following two lines at the very top of the PHP script used for sending the mail - not just in the files I required.
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
?>
Let me know if it works for you as well.
Add all those extra require lines are not going to help; Just load the autoloader, like the original example code says. Try loading it from an absolute path:
require '/full/path/to/PHPMailerAutoload.php';
If that works, you need to check that your include_path setting in php.ini includes the directory you're loading from - for example that it contains . as one of the paths.
I'm pretty convinced this is an environment/config problem, not code, so try a completely minimal script, just this:
<?php
require 'class.phpmailer.php';
$mail = new PHPMailer;
If you're doing new development, you should really be using composer anyway - it completely solves include problems and you'll never have to worry about where your libraries are again.