PHP script fails at $mail = new PHPMailer() without error message - php

This is driving me up a wall!
I'm trying to use phpmailer to send e-mail. Here is my code:
print "about to do the require!";
require_once("$s[phppath]/phpmailer.php");
print "require has been successful! creating a PHPMailer object!";
$mail = new PHPMailer();
print "yay!";
However, the program never gets to "yay", it dies at line 4 ($mail = new PHPMailer();). Most maddening is that no error message is displayed, even though php is running with display_errors = On. To test this, I threw in some obvious errors, like skipping semi-colons at the end of lines, and I immediately get an error message about this.
What the heck is going on here?
Edited
I modified the code like this:
require_once("$s[phppath]/phpmailer.php");
try {
$mail = new PHPMailer(true);
} catch (phpmailerException $e) {
echo $e->errorMessage(); //Pretty error messages from PHPMailer
} catch (Exception $e) {
echo $e->getMessage(); //Boring error messages from anything else!
}
Still no dice.

I am using PHPMailer also. Now in 2018 Version 6.05.
I was also in trouble with creation of $mail = new PHPMailer; I always saw the message that the class could not be created. But I was sure the file with the class was included.
What I found out, was that there is a namespace used within the class PHPMailer.
So the new object does not exist as "PHPMailer" but as class within the namespace PHPMailer\PHPMailer ! (not to be confused with folders of your installation).
What finally worked for me was to write the following line:
$mail = new PHPMailer\PHPMailer\PHPMailer;
// You need to add the namespace part after new and before class PHPMailer

Ok, there were two parts to this question:
1) Why no error messages? I feel very, very stupid about this one, because though I had display_errors turned on, my own script actually disabled error_reporting. Thank you Pathik Ghandi for pointing out this very simple fix. I can be quite special at times.
2) Why was PHPMailer not working? Because apparently PHPMailer now requires TWO files instead of one: class.phpmailer.php is not enough. You now also need PHPMailerAutoload.php. Hope this helps someone down the line!

Try echoing out $s[phppath] to make sure you are getting the right path. Redownload and reupload the phpMailer lib. Try using require instead of require_once. Try using include instead of require. Go into the phpmailer.php file and add in an echo or something to make sure you are actually requiring that file.
To be sure; Are you running some kind of framework? ie Wordpress? If so you may need to set a flag to show PHP error messages. WP: define("WP_DEBUG", true);

Try to call restore_error_handler() function above require.

Related

PHPMailer Mailer Error: The following From address failed: me#x.com : Called MAIL FROM without being connected

Before you classify this post as a duplicate, please note that I've been working on this issue for days and I've reviewed all of the other posts.
Previous solution: Use the latest version of PHPMailer.
I've tried PHPMailer 6.2.0, 6.1.8 , 6.1.7 and older versions
I've tried using the composer and i've also tried using PHPmailer
without the composer.
Sometimes PHPMailer works and sometimes I get the same error. There's no rhyme or reason. I can run the following script and it works with no error, run it 5 seconds later then it doesn't work, run it again 5 seconds later and it works. What the heck?!
require_once("PHPMailer-master/PHPMailerAutoload.php");
also tried:
require "PHPMailer3/PHPMailer-6.2.0/src/PHPMailer.php";
require "PHPMailer3/PHPMailer-6.2.0/src/SMTP.php";
require "PHPMailer3/PHPMailer-6.2.0/src/Exception.php";
use PHPMailer\PHPMailer\PHPMailer;
Lets continue:
$mail = new PHPMailer;
$mail->IsSMTP();
$mail->Host = "10.10.10.38";
$mail->Port = 25;
$mail->SMTPDebug = false;
$mail->SMTPAuth = false;
$mail->SMTPSecure = false;
$mail->SetFrom ("me#x.com", "me");
$mail->AddReplyTo("me#x.com", "me");
$mail->Subject = "I need help fixing you";
$mail->AltBody = "Yes It Worked!";
$body ="Yes It Worked!";
$mail->MsgHTML($body);
$mail->AddAddress("x#x.com", "x");
if(!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}
Another Previous solution: check the from address
At first i thought this was the solution because my from address was a variable but that's not it! I'm using a static from address.
Another Previous solution: the from address is using single quotes but everything else is using double quotes.
Tried that
I've also tried:
$mail->From = "me#x.com";
$mail->FromName = "me#x.com";
What else is there to try?
By the way, i'm running PHP 7.3.21 and i'm using an internal SMTP relay server. Please dont suggest using a different email server. I have to get it working with the current server.
Thanks,
The code you're using looks like it's been copied from a very old example, though I don't think that's the issue here.
require_once("PHPMailer-master/PHPMailerAutoload.php");
that file is obsolete and has been omitted from supported PHPMailer versions since 2017.
I can run the following script and it works with no error, run it 5 seconds later then it doesn't work, run it again 5 seconds later and it works.
This tells you something important – your script (and PHPMailer) is not the source of the problem. The most likely explanation is that your mail server, or a firewall between you and the mail server, has some kind of throttling or rate limiting that's preventing you sending all the time, resulting in inconsistent results.
You're also doing this:
$mail->SMTPDebug = false;
Since you're trying to debug an SMTP issue, don't you think that this might possibly be relevant? Especially since it's one of the first things referred to in the troubleshooting guide I'm sure you've seen already, and used and described in literally hundreds of answers on here. Your very first step should be to set $mail->SMTPDebug = 3; and read what the output says, and post it as part of your question.

Cpanel cronjob not working

I have a php script in root of my site. I have added a cronjob in my cpanel.
It is working with basic database operations like shown below:
<?php
require_once "classes/class.database.php";
$db = new database;
$db->connectToDB();
$data = date("Y/m/d H:i");
$res = $db->insertRow("cron",array("datetime"),array($data));
echo $res;
?>
In same file I have replaced these codes with codes below which are real codes that I want to schedule but it is not working. If I enter manually, it works but by this way it doesnt working.
Real Codes:
<?php
require_once "/home/domain/subdomain.domain.com/share/share.php";
$share = new share;
$share->sharePosts();
?>
I dont think there is an error in my code because it works manually however I want to be sure about that. Can I log output of this file?
Thanks in advance.
I have finally solved the issue.
I have enabled error logging with codes below.
error_reporting(E_ALL);
ini_set("log_errors", 1);
ini_set("error_log", "/tmp/php-error.log");
I have tried to mail myself (it is cpanels property) and just echo something.
Mail came succesfully. Then I wrote wrong code (I wrote wrong path to "required_once"), when I execute manually, gives fatal error. Fatal errors not mailed. After that I replaced "require_once" with "include" to avoid fatal errors, then it noticed an error but this time it mailed to me. Error was "No such file." Then I tried path like that "/home/domain.com/yourcron.php" and no errors. In conclusion, all paths must be like "/home/domain.com/yourcron.php".

Cannot import Google App Engine Api

All I need from my server is to be able to send emails to my users when they forget their password. I try the code below after installing the Google App Engine SDK for PHP and it gives me the error
Fatal error: require_once(): Failed opening required
'google/appengine/api/mail/Message.php' (include_path='.:') in
/Library/WebServer/Documents/AppEngine/testMail.php on line 2
This is my code:
require_once 'google/appengine/api/mail/Message.php';
use google\appengine\api\mail\Message;
try {
$message = new Message();
$message->setSender('test#gmail.com');
$message->addTo('test#example.com');
$message->setSubject('Example email');
$message->setTextBody('Hello, world!');
$message->send();
echo 'Mail Sent';
} catch (InvalidArgumentException $e) {
echo 'There was an error';
}
I'm thinking that I did not install the engine properly but I'm lost at this point. Any ideas?
Well, two things. First of all, you don't need the require_once statement. At least I've never had to use that (maybe you did need it in older versions of GAE but as far as I know, it isn't needed. Your php script is currently trying to open a directory that doesn't exist in your project.) All you need is the use google\appengine\api\mail\Message; statement.
Secondly, when you setSender, you need to make sure that your email 'test#gmail.com' is a registered email in your google app engine app -> otherwise no actual email will get sent.
Hope that helps.

Cannot send mail using Zend library

require_once does not seem to work. I am trying to use Zend libraries to send mail but something does not work. I am using my web hosting server provider so I have to put the libraries in a subdirectory (without installing any framework).
// $path= dirname(__FILE__)."/ZendLibrary:".get_include_path() ;
$path= "./ZendLibrary".PATH_SEPARATOR.get_include_path() ;
set_include_path($path);
//echo $path ;
echo "Spot 0" ;
require_once 'Zend/Mail.php';
echo "Spot 1" ;
I got the "Spot 0" message but I don't get the "Spot 1" message. I have selected only two Zend libraries:
ZendLibrary/Zend/Mail/* (directory)
ZendLibrary/Zend/Mime/* (directory)
ZendLibrary/Zend/Mail.php (script)
ZendLibrary/Zend/Mime.php (script)
ZendLibrary is a folder in the same directory where my script is. What could happening?
UPDATE#1:
My problem is that the code stops working right when I run require_once. It does not echo "Spot 1" message. I have tried absolute paths for set_include_path, I have tried to load a .php library script without internal require_once statements, but nothing makes it work. As my test is run from a web hosting site in the Internet I don't have access to logs!.. or do I?
$path= realpath(dirname(__FILE__).'/ZendLibrary').PATH_SEPARATOR.get_include_path() ;
// $path= "./ZendLibrary".PATH_SEPARATOR.get_include_path() ;
set_include_path($path);
Zend Mail has some dependencies.
Hard dependencies
Zend_Exception
Zend_Loader
Zend_Mime
Zend_Validate
Soft
Zend_Locale
Zend_Date
Zend_Filter
Zend_Registry
The best is to add all Zend library to the include path in PHP and all components will load the dependencies automatically.
You havent met all the dependencies... At the minimum you also need Zend_Exception (all component specific exceptions in the framework extend form this) but im pretty sure there are others that Mail and Mime depend on. Just to make it easy on myself i would also grab Zend/Loader and use it for autoloading.
Update:
I took a look and it seems as though you will also need Zend/Validate and Zend/Loader which is required by one of the classes in Validate component - though Mail only uses Zend/Validate/Hostname (which does depend on the abstract classes and interfaces for Validate as well as Zend_Validate_Ip) so you might be able to get away with not grabbing Zend/Loader, but you might as well jsut make use of it for general purpose autoloading.
As a suggestion you could use [Swift Mailer]1 instead... youll be bale to avoid dependency hell and i like it a lot better anyhow. Only down side is its for Sending mail, while Zend_Mail will also let you read a mail store on a local or remote server.
I used Zend_Mail with SMTP standalone before, here are the files I needed. I also reduced it down to what you need if you only want to use sendmail also.
If you want to use Sendmail, that is the easiest. Your dependencies are:
Zend/Exception.php
Zend/Mail.php
Zend/Mime.php
Zend/Mail/Exception.php
Zend/Mail/Transport/Abstract.php
Zend/Mail/Transport/Exception.php
Zend/Mail/Transport/Sendmail.php
Zend/Mime/Exception.php
Zend/Mime/Message.php
Zend/Mime/Part.php
And with those files, here is an example use:
<?php
// optionally
// set_include_path(get_include_path() . PATH_SEPARATOR . '/path/to/Zend');
require_once 'Zend/Mail.php';
require_once 'Zend/Mail/Transport/Sendmail.php';
$transport = new Zend_Mail_Transport_Sendmail();
$mail = new Zend_Mail();
$mail->addTo('user#domain')
->setSubject('Mail Test')
->setBodyText("Hello,\nThis is a Zend Mail message...\n")
->setFrom('sender#domain');
try {
$mail->send($transport);
echo "Message sent!<br />\n";
} catch (Exception $ex) {
echo "Failed to send mail! " . $ex->getMessage() . "<br />\n";
}
If you need SMTP, then you have a few more dependencies as prodigitalson showed. In addition to the above you need at least:
Zend/Loader.php
Zend/Registry.php
Zend/Validate.php
Zend/Mail/Protocol/Abstract.php
Zend/Mail/Protocol/Smtp.php
Zend/Mail/Transport/Smtp.php
Zend/Validate/Abstract.php
Zend/Validate/Hostname.php
Zend/Validate/Interface.php
Zend/Validate/Ip.php
Zend/Validate/Hostname/*
Zend/Mail/Protocol/Smtp/Auth/*
Then you can do something like this:
<?php
require_once 'Zend/Mail.php';
require_once 'Zend/Mail/Transport/Smtp.php';
$config = array(//'ssl' => 'tls',
'port' => '25', //465',
'auth' => 'login',
'username' => 'user',
'password' => 'password');
$transport = new Zend_Mail_Transport_Smtp('smtp.example.com', $config);
$mail = new Zend_Mail();
$mail->addTo('user#domain')
->setSubject('Mail Test')
->setBodyText("Hello,\nThis is a Zend Mail message...\n")
->setFrom('sender#domain');
try {
$mail->send($transport);
echo "Message sent!<br />\n";
} catch (Exception $ex) {
echo "Failed to send mail! " . $ex->getMessage() . "<br />\n";
}
Answer:
My ISP (web hosting too) has a setting to disable require_once. I was able to setup a Unbuntu virtual machine on VirtualBox and set up a web server. I copied the content of my test web site in my Unbuntu and find out that require_once does work as expected !!! That may explain why the server-side include did not work for me either. The following was a usefull check, that indicated me the file was in the expected place.
$file = 'ZendLibrary/Zend/Mail.php';
if ((!is_file($file)) or (!is_readable($file)))
die("File does not exists or is not readable.");
Now I have to find out why it is disabled, how to enable it, or just switch web hosting company. Update: I had to pay $20 dolars a year more for the provider to enable PHP (in this case to be able to include).
This site can tell you more about it.

How to disable error messages in PHPMailer?

How do I disable the error messages from the PHPMailer class? I'm displaying my own error messages and I don't want users to see errors such as "SMTP Error: Could not connect to SMTP host."
Thanks
I know this thread is old and already answered but I stumbled here because I had the same problem but ending up solving it differently so I thought I'd share. NOTE: I'm using PHPMailer v5.1.
When you instantiate the PHPMailer class, it takes one optional argument, $exceptions. That tells PHPMailer if it should throw exceptions if it encounters any. It defaults to false which means it does not throw any exceptions, just echoes its messages out. However, if you call it like
$mail = new PHPMailer(true);
you will tell it to throw exceptions. You can then catch those exceptions and deal with them however you choose. To me, that is much cleaner and more elegant than messing with the source code or disabling the error reporting.
This is the way PHPMailer wants you to do it; does not involve editing the original class file.
$mail->SMTPDebug = false;
$mail->do_debug = 0;
This is not probably the best solution, but it works.
In your phpmailer library folder open "class.phpmailer.php",
find
public function Send()
inside it comment the line
echo $e->getMessage()."\n";
There are two ways that work pretty much the same as of May 2020
$mail->SMTPDebug = 0;
OR
$mail->SMTPDebug = false;
There's a better solution (I think :) ), it's an improved version of the solution sugested by Riccardo
In the file "class.phpmailer.php", within the function
public function Send()
find the line
echo $e->getMessage()."\n";
and replace it for this
if ($SMTPDebug)
echo $e->getMessage()."\n";
In this way, it will only show the exceptions messages (or error messages) if you are running in debug mode..
Hope it helps!!
regards!!
//Enable SMTP debugging
// 0 = off (for production use)
// 1 = client messages
// 2 = client and server messages
$mail->SMTPDebug = 2;
Here's another solution:
ob_start(); //start output buffering to capture all output and prevent errors from being displayed
$delivery = $mail->Send();
ob_end_clean(); //erase the buffer and stop output buffering
I needed to suppress errors from the JUtility::sendMail function in Joomla, which uses PHPMailer behind the scenes, so the above answers didn't work for me but output buffering did the trick.
If the errors are coming from the call to $mail->Send(); then you can do something like this:
$oldErrorSetting = error_reporting(0); // temporarily disable warnings
$delivery = $mail->Send();
error_reporting($oldErrorSetting); // restore error setting
This will suppress PHP errors that come from the Send call.
Then, to get PHPMailer's errors and do something nice with them, you can use the $delivery return value and ErrorInfo:
if (!$delivery) {
$errorDetails = $mail->ErrorInfo;
print "<p>$errorDetails</p>\n";
}
I'm having a problem with the error: Can not modify header information - headers already sent by (output started at /phpMailer/class.phpmailer.php) because my return json needs header ('Content-Type: application / json') ; And was giving error because the class class.phpmailer.php printed on the screen the error Invalid address: which generates the error of the header so to solve it was simple, it only includes in the class class.phpmailer.php in the following line the debug check and it worked Perfectly follows
This line
Echo $ this-> Lang ('invalid_address'). ':'. $ Address;
Change to:
If ($ this-> SMTPDebug) {
       Echo $ this-> Lang ('invalid_address'). ':'. $ Address;
  }
Delete below code if included
$mail->SMTPDebug = SMTP::DEBUG_SERVER;

Categories