"use PHPMailer\PHPMailer\PHPMailer" not working - php

I am trying to make a form that can contact me via email with PHP. I am new to PHP so after watching a couple of videos I am making with PHPMailer. After I downloaded the zip file from GitHub and installing composer and these things, the code shows some errors. When I declare "use\PHPMailer\PHPMailer\PHPMailer," it says Unexpected, 'Unknown'.
My code is this
<?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;
//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 = 'smtp.example.com'; //Set the SMTP server to send through
$mail->SMTPAuth = true; //Enable SMTP authentication
$mail->Username = 'user#example.com'; //SMTP username
$mail->Password = 'secret'; //SMTP password
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; //Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged
$mail->Port = 587; //TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
//Recipients
$mail->setFrom('from#example.com', 'Mailer');
$mail->addAddress('joe#example.net', 'Joe User'); //Add a recipient
$mail->addAddress('ellen#example.com'); //Name is optional
$mail->addReplyTo('info#example.com', 'Information');
$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}";
}
?>
The code is from the GitHub page I just copied and pasted it to test it. I edited the JSON file and all of them but it doesn't work.
Appreciate the help from everyone. Thank you

The most likely explanation is that you are running PHP that’s older than version 5.3, which is when namespaces and the use statement were introduced. Upgrade your PHP - any new development should be using 8.0.

Move your autoload to the top of the file, using PSR4 before the autoload is in wont work.
<?php
require 'vendor/autoload.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;
...
Though you should really keep your autoloader in a seperate file. e.g. a index.php and create a Mailer class of your own.
How you would go about doing this would be adding an autoload to your composer.json
{
"name": "acme/app",
"type": "project",
"authors": [
{
"name": "some name",
"email": "email#example.com"
}
],
"require": {
"phpmailer/phpmailer": "^6.4"
},
"autoload": {
"psr-4": {"Acme\\": "src/"}
}
}
Creating a src folder with a file named App.php
<?php
namespace Acme;
class App
{
public static function boot()
{
echo 'works'; // Do what ever you want.
}
}
Create a index.php in the root
<?php
require 'vendor/autoload.php';
Acme\App::boot();
then run composer install or composer du and run php index.php and your set.

I have seen cases where the classes were placed inside a PHP function. That will throw an error.
From the documentation:
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;

Related

Using PHPMailer without Composer

I just tried this example:
// for use PHP Mailer without composer :
// ex. Create a folder in root/PHPMAILER
// Put on this folder this 3 files find in "src"
// folder of the distribution :
// PHPMailer.php , SMTP.php , Exception.php
// include PHP Mailer
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
include dirname(__DIR__) .'/PHPMAILER/PHPMailer.php';
include dirname(__DIR__) .'/PHPMAILER/SMTP.php';
include dirname(__DIR__) .'/PHPMAILER/Exception.php';
// i made a function
/*
*
* Function send_mail_by_PHPMailer($to, $from, $subject, $message);
* send a mail by PHPMailer method
* #Param $to -> mail to send
* #Param $from -> sender of mail
* #Param $subject -> suject of mail
* #Param $message -> html content with datas
* #Return true if success / Json encoded error message if error
* !! need -> classes/Exception.php - classes/PHPMailer.php - classes/SMTP.php
*
*/
function send_mail_by_PHPMailer($to, $from, $subject, $message){
// SEND MAIL by PHP MAILER
$mail = new PHPMailer();
$mail->CharSet = 'UTF-8';
$mail->isSMTP(); // Use SMTP protocol
$mail->Host = 'your_host.com'; // Specify SMTP server
$mail->SMTPAuth = true; // Auth. SMTP
$mail->Username = 'my_mail#your_host.com'; // Mail who send by PHPMailer
$mail->Password = 'your_passord_of_your_box'; // your pass mail box
$mail->SMTPSecure = 'ssl'; // Accept SSL
$mail->Port = 465; // port of your out server
$mail->setFrom($from); // Mail to send at
$mail->addAddress($to); // Add sender
$mail->addReplyTo($from); // Adress to reply
$mail->isHTML(true); // use HTML message
$mail->Subject = $subject;
$mail->Body = $message;
// SEND
if( !$mail->send() ){
// render error if it is
$tab = array('error' => 'Mailer Error: '.$mail->ErrorInfo );
echo json_encode($tab);
exit;
}
else{
// return true if message is send
return true;
}
}
/*
*
* END send_mail_by_PHPMailer($to, $from, $subject, $message)
* send a mail by PHPMailer method
*
*/
// use function :
send_mail_by_PHPMailer($to, $from, $subject, $message);
When calling new PHPMailer() the system throws a error:
Can't find class PHPMailer.
The include of the files works fine. What is wrong?
You could try reading the readme (which should be the first place you look anyway), which tells you the right way to load PHPMailer without composer.
I expect the problem is that you are using include instead of require, and the classes are failing to load, so that when you try to make an instance, it's not defined, giving you the error you're seeing. Your script will not work without those files, so you want it to fail if they can't be loaded.
There's a lesson though - learn to use composer and understand how it works. As a PHP novice, it's the single best thing you can do.

PHPMailer Class 'PHPMailer' not found error [duplicate]

This question already has answers here:
Fatal error: Class 'PHPMailer' not found
(12 answers)
Closed 3 years ago.
I'm getting the error : Class 'PHPMailer' not found in PHPMailer
I know the answer is probably out there but for my code, I can't seem to work it out.
I have a .php file where I created a class called Email, then a function inside this called sendEmail. Inside this function there is the PHPMailer files and code to send an email.
My code is :
function sendMail($con, $siteName, $siteLogo, $email1, $email2, $email3, $email4, $email5, $title, $message, $buttonText, $buttonLink) {
# Get the variables of the email using the variables inside the function's brackets upon request
error_reporting(E_ALL);
global $gmailEmail;
global $gmailPassword;
global $siteUrl;
require $siteUrl.'PHPMailer/PHPMailer.php';
require $siteUrl.'PHPMailer/SMTP.php';
require $siteUrl.'PHPMailer/Exception.php';
$mail = new PHPMailer;
$body = $this->emailTemplate($con, $siteName, $siteLogo, $email1, $email2, $email3, $email4, $email5, $title, $message, $buttonText, $buttonLink);
$mail->Host = "smtp.gmail.com";
$mail->SMTPDebug = 1;
$mail->SMTPAuth = true;
$mail->Host = "smtp.gmail.com";
$mail->Port = 587;
$mail->Username = $gmailEmail;
$mail->Password = $gmailPassword;
$mail->SetFrom("admin#".$siteName, $sitename." Admin");
$mail->AddReplyTo("admin#".$siteName, $sitename." Admin");
$mail->Subject = $title;
$mail->AltBody = "To view the message, please use an HTML compatible email viewer!";
$mail->MsgHTML($body);
$emails = array($email1, $email2, $email3, $email4, $email5);
# Foreach email that is not empty, send the email
foreach((array)$emails as $email) {
$mail->AddAddress($email);
if (!$mail->Send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}
}
}
But the error lies on the line of the code: $mail = new PHPMailer; , saying Class 'PHPMailer' not found
Someone said it's the use's :
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
But whenever I include these, I get this error: Class 'PHPMailer\PHPMailer\PHPMailer' not found
You don't have to have composer (though it's a good idea), but if you don't, you do have to load the classes yourself, and you have to import them into your namespace with use statements. All of this is covered in the readme and examples provided with PHPMailer, so it's not exactly kept secret.
The use statements must appear at the top of your script, before you try to use the classes, so perhaps the problem is that you're putting them within your function, which won't work – all that is standard PHP syntax, nothing unusual.
Alternatively you can use fully qualified class names, like this:
$mail = new PHPMailer\PHPMailer\PHPMailer;
Also I can see that you've based your code on a very old, obsolete example. That'a a bad idea - always use the latest.

How to integrate PHPMailer with Codeigniter 3

Hi I am trying to use PHPMailer Library from GitHUB in my Codeigniter application.
I downloaded the code and unzipped in my application\library folder.
So there I have a folder called vendor inside which resides the source code for PHPMailer.
Now I created a File named Bizmailer_Controller.php.
<?php defined('BASEPATH') OR exit('No direct script access allowed');
/**
*
*/
class Bizmailer_Controller extends CI_Controller
{
public function __construct()
{
parent::__construct();
require "vendor\phpmailer\phpmailer\PHPMailerAutoload";
$this->Bizmailer = new PHPMailer();
//Set the required config parameters
$this->Bizmailer->isSMTP(); // Set mailer to use SMTP
$this->Bizmailer->Host = 'smtp1.example.com;smtp2.example.com'; // Specify main and backup SMTP servers
$this->Bizmailer->SMTPAuth = true; // Enable SMTP authentication
$this->Bizmailer->Username = 'user#example.com'; // SMTP username
$this->Bizmailer->Password = 'secret'; // SMTP password
$this->Bizmailer->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
$this->Bizmailer->Port = 465;
//return $api;
}
}
Now in my controllers I am trying to load it like this :
$this->load->library('Bizmailer');
$mail = new Bizmailer();
And I Get this error :
An Error Was Encountered
Unable to load the requested class: Bizmailer
So Please guide me how I can load or integrate this library in Codeigniter.
here is a guide
1. installing PHP Mailer
Download the latest PHPMailer Build from Github.
You can find the project here
Click now on "clone or download" and download it as zip - as in the image below is shown.
The folder in the zip is called PHPMailer-master.
Unzip this in your application/third_party/ folder and rename the folder to phpmailer. You should see something like this
2. PHP Mailer Library
Imho its best to create a library which handles your PHPMailer Object (Phpmailer_library.php)
This library could look like
class Phpmailer_library
{
public function __construct()
{
log_message('Debug', 'PHPMailer class is loaded.');
}
public function load()
{
require_once(APPPATH."third_party/phpmailer/PHPMailerAutoload.php");
$objMail = new PHPMailer;
return $objMail;
}
}
3. Using this library in one of your controllers, models etc.
class Welcome extends CI_Controller {
public function index()
{
$this->load->library("phpmailer_library");
$objMail = $this->phpmailer_library->load();
}
}
i think this should pretty much do the job.
If you've any troubles, don't hesitate to ask ;)
Update 25.06.2018
Since the PHPMailer guys removed the autoloader you've two options now:
1.) via Composer
for those who didn't know - Codeigniter supports Composer - you simply have to activate the autoload - you can find this in your config.php
$config['composer_autoload'] = true;
For more informations take a look here
After that - run composer like
composer require phpmailer/phpmailer
You now should have within your application/vendor folder the phpmailer files.
The library should look like
class Phpmailer_library
{
public function __construct()
{
log_message('Debug', 'PHPMailer class is loaded.');
}
public function load()
{
$objMail = new PHPMailer\PHPMailer\PHPMailer();
return $objMail;
}
}
2.) download
follow step 1
The library should look like
class Phpmailer_library
{
public function __construct()
{
log_message('Debug', 'PHPMailer class is loaded.');
}
public function load()
{
require_once(APPPATH.'third_party/phpmailer/src/PHPMailer.php');
require_once(APPPATH.'third_party/phpmailer/src/SMTP.php');
$objMail = new PHPMailer\PHPMailer\PHPMailer();
return $objMail;
}
}
and everything else should remain the same
**
UPDATE AUGUST 2019
**
At first, download the latest PHPMailer library files and place all the files in the application/third_party/ folder of your CodeIgniter application.
Now, create a library (application/libraries/Phpmailer_lib.php) to handle the PHPMailer object.
Include the PHPMailer library files.
Initialize the PHPMailer class.
Return the PHPMailer object.
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
class PHPMailer_Lib
{
public function __construct(){
log_message('Debug', 'PHPMailer class is loaded.');
}
public function load(){
// Include PHPMailer library files
require_once APPPATH.'third_party/phpmailer/Exception.php';
require_once APPPATH.'third_party/phpmailer/PHPMailer.php';
require_once APPPATH.'third_party/phpmailer/SMTP.php';
$mail = new PHPMailer(true);
return $mail;
}
}
Now send email via SMTP server using PHPMailer from your controller using this code.
class Email extends CI_Controller{
function __construct(){
parent::__construct();
}
function send(){
// Load PHPMailer library
$this->load->library('phpmailer_lib');
// PHPMailer object
$mail = $this->phpmailer_lib->load();
// SMTP configuration
$mail->isSMTP();
$mail->Host = 'smtp.example.com';
$mail->SMTPAuth = true;
$mail->Username = 'user#example.com';
$mail->Password = '********';
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
$mail->setFrom('info#example.com', 'CodexWorld');
$mail->addReplyTo('info#example.com', 'CodexWorld');
// Add a recipient
$mail->addAddress('john.doe#gmail.com');
// Add cc or bcc
$mail->addCC('cc#example.com');
$mail->addBCC('bcc#example.com');
// Email subject
$mail->Subject = 'Send Email via SMTP using PHPMailer in CodeIgniter';
// Set email format to HTML
$mail->isHTML(true);
// Email body content
$mailContent = "<h1>Send HTML Email using SMTP in CodeIgniter</h1>
<p>This is a test email sending using SMTP mail server with PHPMailer.</p>";
$mail->Body = $mailContent;
// Send email
if(!$mail->send()){
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
}else{
echo 'Message has been sent';
}
}
}
There is php mailer library for Codeigniter 2/3, you can check this and this.

Unable load files within library in Codeigniter

I've written a function within Controller to use PHPMailer and it works fine. After that I need this Function frequently and eventually I decide to write Library. But when do this and load Library within Controller, It has error like this :
Message: Call to undefined method PHPMailerOAuth::isSMTP()
After all I've figured out there is problem with path! I've tried what ever you're thinking but it doesn't work!
I've tried Controller as library
I've tried include(),require_once(),require, with or without APPATH.
I've search as much as I could. Even I've read about Third Party but I don't understand.
Is there any idea to load PHPMailer file within Library?
Thank you in advance.
It's library called PHPMailer.php
class PHPMailer {
public function singleMail($setFromTitle,$setToMail,$setToName,$setSubject,$setMessage)
{
date_default_timezone_set('Etc/UTC');
require 'vendor/phpmailer/phpmailer/PHPMailerAutoload.php';
require 'vendor/autoload.php';
$mail = new PHPMailerOAuth;
$mail->CharSet = 'UTF-8';
$mail->isSMTP();
$mail->SMTPDebug = 2;
$mail->Debugoutput = 'html';
$mail->Host = 'smtp.gmail.com';
$mail->Port = 587;
$mail->SMTPSecure = 'tls';
$mail->SMTPAuth = true;
$mail->AuthType = 'XOAUTH2';
$mail->oauthUserEmail = "XXX#gmail.com";
$mail->oauthClientId = "XXX";
$mail->oauthClientSecret = "XXX";
$mail->oauthRefreshToken = "XXX";
$mail->setFrom('XXXy#zounkan.com', $setFromTitle);
$mail->addAddress($setToMail, $setToName);
$mail->Subject = $setSubject;
$mail->msgHTML($setMessage);
if (!$mail->send()) {
echo "Mailer Error: " . $mail->ErrorInfo;
} else {
echo "Message sent!";
}
}
And it's how I load this library within Controller's function :
$this->load->library('PHPMailer');
$this->phpmailer->singleMail($setFromTitle,$setToMail,$setToName,$setSubject,$setMessage);
According to PHPMailer's owner, he helped me and eventually solve this problem!
It should happen for every programmer and when I fixed it I surprised! The problem was about the class name! I define PHPMailer class as Library's class and it's not allowed! So intead of code above (That I'v mentioned) I should try this and it works fine as well :
class Sendingmail {
public function singleMail($setFromTitle,$setToMail,$setToName,$setSubject,$setMessage) {
// Rest of codes
}
}
So don't named your class to PHPMailer or something like this which probably has defined in core functions!

PHP Mailer is sending Duplicated Email (two emails at once)

PHP mailer is sending two emails at once i tried to send it without loop just a single email but it was the same result
I found this here on stackoverflow but not changing anything
$mail->SingleTo = true;
So what can i do for this how can i send only one email per recipient ?
Here is my custom Mailer class
class Mailer
{
public static function sendMail($subject, $msgWithHtml, $msgNotHtml, array $recipients, array $attachmentPath = null )
{
$mail = new \PHPMailer;
//$mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'mail.lotfio-lakehal.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'noreplay#lotfio-lakehal.com'; // SMTP username
$mail->Password = '------------'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
$mail->setFrom('noreplay#lotfio-lakehal.com');
foreach($recipients as $email)
{
$mail->addAddress($email); // Add a recipient // Name is optional
}
$mail->SingleTo = true; //will send mail to each email address individually
$mail->addReplyTo('contact#lotfio-lakehal.com', 'Information');
if($attachmentPath){
foreach($attachmentPath as $file)
{
$mail->addAttachment($file);
}
}
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $msgWithHtml;
$mail->AltBody = $msgNotHtml;
return $mail->send();
}
}
and here is how iam calling this method
use fordev\app\helpers\Mailer;
Mailer::sendMail('Email test from mailer', '<div></div>', 'qdqsdq dqsdqsdqsd', ['lotfiolakehal#gmail.com','contact#lotfio-lakehal.com']);
SingleTo with The SMTP Transport
The SingleTo is only supported in "mail" and "sendmail" transports, not in "SMTP".
Since you use the "SMTP" transport, The SingleTo won't work. The authors of the PHPMailer class should have thrown an exception to exclude cases like that when when the SingleTo is not actually honored. If you use the SMTP transport, just loop the send for each address one-by-one (just call $mail->addAddress one time to pass just one address for each instance of the PHPMailer class), and don't touch the SingleTo property value, keep it default (false).
Plans on SingleTo in Future Versions of The PHPMailer
SingleTo is planned to be deprecated in the release of PHPMailer 6.0, and removed in 7.0. The authors of PHPMailer expalained that it's better to control sending to multiple recipients at a higher level:
PHPMailer isn't a mailing list sender.
Source: https://github.com/PHPMailer/PHPMailer/issues/1042
Use of the PHP mail() function needs to be discouraged because it's extremely difficult to use safely; SMTP is faster, safer, and gives more control and feedback."
Your Question
The question was "So what can i do for this how can i send only one email per recipient?"
Just modify the arguments of the sendMail and change it from "array $recipients" to just a single $recipient, so it will the this:
public static function sendMail($subject, $msgWithHtml, $msgNotHtml, $recipient, array $attachmentPath = null )
And replace the following code
foreach($recipients as $email)
{
$mail->addAddress($email); // Add a recipient // Name is optional
}
to
$mail->addAddress($recipient);
If you cannot modify the declaration of the sendMail function since it's alreay used by other code, keep it, but move all its code to another function:
public static function sendMailSingleRecipient($subject, $msgWithHtml, $msgNotHtml, $recipient, array $attachmentPath = null )
so the code of the function sendMail will be like that:
foreach($recipients as $email)
{
self::sendMailSingleRecipient($subject, $msgWithHtml, $msgNotHtml, $email, $attachmentPath)
}
The whole code will be the following:
class Mailer
{
public static function sendMailSingleRecipient($subject, $msgWithHtml, $msgNotHtml, $recipient, array $attachmentPath = null )
{
$mail = new \PHPMailer;
//$mail->SMTPDebug = 3; // Enable verbose debug output
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'mail.lotfio-lakehal.com'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'noreplay#lotfio-lakehal.com'; // SMTP username
$mail->Password = '------------'; // SMTP password
$mail->SMTPSecure = 'ssl'; // Enable TLS encryption, `ssl` also accepted
$mail->Port = 465; // TCP port to connect to
$mail->setFrom('noreplay#lotfio-lakehal.com');
$mail->addAddress($recipient); // Add a recipient // Name is optional
$mail->addReplyTo('contact#lotfio-lakehal.com', 'Information');
if($attachmentPath){
foreach($attachmentPath as $file)
{
$mail->addAttachment($file);
}
}
$mail->isHTML(true); // Set email format to HTML
$mail->Subject = $subject;
$mail->Body = $msgWithHtml;
$mail->AltBody = $msgNotHtml;
return $mail->send();
}
public static function sendMail($subject, $msgWithHtml, $msgNotHtml, array $recipients, array $attachmentPath = null )
{
foreach($recipients as $email)
{
self::sendMailSingleRecipient($subject, $msgWithHtml, $msgNotHtml, $email, $attachmentPath)
}
}
}
If you still don't like that the sendMail function loops for each of the addresses, but you need to use the smtp transport (not sendmail and not mail) don't use the \PHPMailer class from that third-party library hosted at GitHub and implement the smtp transport by yourself. You will anyway have to send each message separately to the SMTP server over the TCP/IP connection, but each message will have only one "To:" recipient and the messages would not duplicate.
PHP Log
If you suspect that the existing code is still but the function is called twice, just add logging capabilities to your code and check how many times it has been called. If you can see php error log, just add the error_log() to the beginning of the function, e.g.
error_log(print_r($recipients, true));
or
error_log(implode(',', $recipients));
So you will see from the log how many times the function have been actually called. Just don't forget to remove the error_log line from your code. If you don't have access to the error log file, use file_put_contents:
file_put_contents($filepath, implode(',', $recipients).PHP_EOL, FILE_APPEND);
Before calling it, set $filepath to the path name of the file to which you have access.
I had the same problem. This happens if you call $mail->Send() twice.
Delete the send function of your PHPmailer config file, and add an if statement at the end of your instruction:
include ("../PHPMailer/sendEmail.php");
if($mail->Send()) {
echo "ok";
} else {
echo "fail";
}

Categories