Jump to content

PHPMailer as function


Go to solution Solved by DennisF,

Recommended Posts

I am trying to use PHPMailer as a function. I mean I want to call the PHPMailer script "off the shelf and working" see code  phpmailer.php from another script by just simply putting the whole script phpmailer.php into a function func($somearray) { ... }  and then call and use it when I need it.
But I cant get it to work.

phpmailer.php, the working script is here:
 

<?php
	ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);


use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

// Include PHPMailer autoloader or include necessary PHP files
require 'PHPMailer/src/PHPMailer.php';
require 'PHPMailer/src/SMTP.php';
require 'PHPMailer/src/Exception.php';

// Create a new PHPMailer instance
$mail = new PHPMailer(true); // Enable exceptions

try {
    // SMTP configuration
    $mail->isSMTP();
    $mail->Host = 'mail.qss.mgo.mybluehost.me'; // Your SMTP server host
    $mail->SMTPAuth = true;
    $mail->Username = 'xxxxx'; // Your SMTP username
    $mail->Password = 'xxxxx'; // Your SMTP password
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption
    $mail->Port = 587; // TCP port to connect to

    // Sender and recipient addresses
    $mail->setFrom('xxxxx', 'Your Name'); // Sender's email address and name
    $mail->addAddress('xxxxx', 'Recipient Name'); // Recipient's email address and name

    // Email content
    $mail->isHTML(true); // Set email format to HTML
    $mail->Subject = 'Test Email';
    $mail->Body = 'This is a test email sent using PHPMailer';

    // Send the email
    if ($mail->send()) {
        echo 'Email sent successfully!';
    } else {
        echo 'Error: Email not sent.';
    }
} catch (Exception $e) {
    echo 'Error: ' . $e->getMessage();
}


?>



First issue was that the code section:
 

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

makes trouble when inside the function. So I put it into my calling script at the top.
So my calling script is test.php:
 

<?php
	// Start the session
	session_start();
	ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    use PHPMailer\PHPMailer\PHPMailer;
    use PHPMailer\PHPMailer\SMTP;
    use PHPMailer\PHPMailer\Exception;

	require 'testfunctions.php';
	
	echo "1<br>";
	$dummy=func();
	echo "2<br>";
	exit;
?>

and the rest is in testfunctions.php:

<?php
function func() {
	ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);
    
    // 3 lines taken from here...

    // Include PHPMailer autoloader or include necessary PHP files
    require 'PHPMailer/src/PHPMailer.php';
    require 'PHPMailer/src/SMTP.php';
    require 'PHPMailer/src/Exception.php';
    
    // Create a new PHPMailer instance
    $mail = new PHPMailer(true); // Enable exceptions
    
    try {
        // SMTP configuration
        $mail->isSMTP();
        $mail->Host = 'mail.qss.mgo.mybluehost.me'; // Your SMTP server host
        $mail->SMTPAuth = true;
        $mail->Username = 'xxxxx'; // Your SMTP username
        $mail->Password = 'xxxxx'; // Your SMTP password
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption
        $mail->Port = 587; // TCP port to connect to
    
        // Sender and recipient addresses
        $mail->setFrom('xxxxx', 'Your Name'); // Sender's email address and name
        $mail->addAddress('xxxxx', 'Recipient Name'); // Recipient's email address and name
    
        // Email content
        $mail->isHTML(true); // Set email format to HTML
        $mail->Subject = 'Test Email';
        $mail->Body = 'This is a test email sent using PHPMailer';
    
        // Send the email
        if ($mail->send()) {
            echo 'Email sent successfully!';
        } else {
            echo 'Error: Email not sent.';
        }
    } catch (Exception $e) {
        echo 'Error: ' . $e->getMessage();
    }
}
?>


 

so now I am getting a (not found) message after my 1 is printed to screen...
1

Fatal error: Uncaught Error: Class "PHPMailer" not found in /home2/qssmgomy/public_html/parque-carolina.com/Y/testfunctions.php:15 Stack trace: #0 /home2/qssmgomy/public_html/parque-carolina.com/Y/test.php(15): func() #1 {main} thrown in /home2/qssmgomy/public_html/parque-carolina.com/Y/testfunctions.php on line 15

Of course the two files testfunctions.php and test.php are right next to one another in the same folder as the working file phpmailer.php.

Any help greatly appreciated.

Edited by DennisF
Link to comment
Share on other sites

The issue you're encountering is due to the fact that the PHPMailer classes are not being autoloaded properly within your function func() in the testfunctions.php file. This is happening because the use statements are not sufficient to autoload the classes within the function scope.

To resolve this issue, you can use require_once to include the necessary PHPMailer files within the function scope of func().

<?php

function func() {
    ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

    // Include PHPMailer autoloader or include necessary PHP files
    require_once 'PHPMailer/src/PHPMailer.php';
    require_once 'PHPMailer/src/SMTP.php';
    require_once 'PHPMailer/src/Exception.php';

    // Create a new PHPMailer instance
    $mail = new PHPMailer(true); // Enable exceptions

    try {
        // SMTP configuration
        $mail->isSMTP();
        $mail->Host = 'mail.qss.mgo.mybluehost.me'; // Your SMTP server host
        $mail->SMTPAuth = true;
        $mail->Username = 'xxxxx'; // Your SMTP username
        $mail->Password = 'xxxxx'; // Your SMTP password
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption
        $mail->Port = 587; // TCP port to connect to

        // Sender and recipient addresses
        $mail->setFrom('xxxxx', 'Your Name'); // Sender's email address and name
        $mail->addAddress('xxxxx', 'Recipient Name'); // Recipient's email address and name

        // Email content
        $mail->isHTML(true); // Set email format to HTML
        $mail->Subject = 'Test Email';
        $mail->Body = 'This is a test email sent using PHPMailer';

        // Send the email
        if ($mail->send()) {
            echo 'Email sent successfully!';
        } else {
            echo 'Error: Email not sent.';
        }
    } catch (Exception $e) {
        echo 'Error: ' . $e->getMessage();
    }
}
?>

i hope With this change, PHPMailer classes should be properly included within the func() function scope, and you should be able to call func() from your test.php script without encountering the "Class not found" error.

Best regard

Danish Hafeez | QA Assistant

ICTInnovations

Link to comment
Share on other sites

I am sorry but that does not work.
It is quite confusing.

You mention the "use statement not being sufficient (its in the calling script) but then in the code you supplied you changed the require into require_once in the function.
Still I tested both variations. None worked.

 

Error if I change the require statement to require_once in the function script as you did in the code you supplied:

Fatal error: Uncaught Error: Class "PHPMailer" not found in /home2/qssmgomy/public_html/parque-carolina.com/Y/testfunctions.php:15 Stack trace: #0 /home2/qssmgomy/public_html/parque-carolina.com/Y/test.php(15): func() #1 {main} thrown in /home2/qssmgomy/public_html/parque-carolina.com/Y/testfunctions.php on line 15

 

 

and if I Change the use stetement in the calling script as I assume you intended:
Fatal error: Uncaught Error: Undefined constant "PHPMailer\PHPMailer\PHPMailer" in /home2/qssmgomy/public_html/parque-carolina.com/Y/test.php:8 Stack trace: #0 {main} thrown in /home2/qssmgomy/public_html/parque-carolina.com/Y/test.php on line 8

So neither works...

 

 

 

 

 

 

Link to comment
Share on other sites

Ok, does not work either... 

will recap and reformulate the problem more simply:

I have a WORKING script: phpmailer.php, see the first code posted in this thread.
I am enclosing the whole script in a function:

func() { the whole script unchaged goes here }

then I am calling the function:

<?php
	// Start the session
	session_start();
	ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);


	require 'testfunctions.php';
	
	echo "1<br>";
	$dummy=func();
	echo "2<br>";
	exit;
?>

and I get this error:
Parse error: syntax error, unexpected token "use" in /home2/qssmgomy/public_html/parque-carolina.com/Y/testfunctions.php on line 3

It does not work if I change "use" to require_once. Then I get this error:
Fatal error: Uncaught Error: Undefined constant "PHPMailer\PHPMailer\PHPMailer" in /home2/qssmgomy/public_html/parque-carolina.com/Y/testfunctions.php:3 Stack trace: #0 /home2/qssmgomy/public_html/parque-carolina.com/Y/test.php(12): func() #1 {main} thrown in /home2/qssmgomy/public_html/parque-carolina.com/Y/testfunctions.php on line 3


Please help

Link to comment
Share on other sites

Closing in on the problem.
This works:

<?php
	// Start the session
	// session_start();
	include 'testfunctions.php';
	ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;    
    
 // Include PHPMailer autoloader or include necessary PHP files
require_once 'PHPMailer/src/PHPMailer.php';
require_once 'PHPMailer/src/SMTP.php';
require_once 'PHPMailer/src/Exception.php';
   
    
    
// Create a new PHPMailer instance
$mail = new PHPMailer(true); // Enable exceptions

try {
    // SMTP configuration
    $mail->isSMTP();
    $mail->Host = 'mail.qss.mgo.mybluehost.me'; // Your SMTP server host
    $mail->SMTPAuth = true;
    $mail->Username = 'xxxxx'; // Your SMTP username
    $mail->Password = 'xxxxx'; // Your SMTP password
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption
    $mail->Port = 587; // TCP port to connect to

    // Sender and recipient addresses
    $mail->setFrom('xxx.com', 'Your Name'); // Sender's email address and name
    $mail->addAddress('xxx.com', 'Recipient Name'); // Recipient's email address and name

    // Email content
    $mail->isHTML(true); // Set email format to HTML
    $mail->Subject = 'Test Email';
    $mail->Body = 'This is a test email sent using PHPMailer';

    // Send the email
    if ($mail->send()) {
        echo 'Email sent successfully!';
    } else {
        echo 'Error: Email not sent.';
    }
} catch (Exception $e) {
    echo 'Error: ' . $e->getMessage();
}

	echo "1<br>";
	// $dummy=func();
	echo "2<br>";
	exit;
?>

This does not!:

<?php
	// Start the session
	// session_start();
	include 'testfunctions.php';
	ini_set('display_errors', 1);
    ini_set('display_startup_errors', 1);
    error_reporting(E_ALL);

function func() {                          // the whole thing unchaged inide a function
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;    
    
 // Include PHPMailer autoloader or include necessary PHP files
require_once 'PHPMailer/src/PHPMailer.php';
require_once 'PHPMailer/src/SMTP.php';
require_once 'PHPMailer/src/Exception.php';
   
    
    
// Create a new PHPMailer instance
$mail = new PHPMailer(true); // Enable exceptions

try {
    // SMTP configuration
    $mail->isSMTP();
    $mail->Host = 'mail.qss.mgo.mybluehost.me'; // Your SMTP server host
    $mail->SMTPAuth = true;
    $mail->Username = 'xxxxx'; // Your SMTP username
    $mail->Password = 'xxxxx'; // Your SMTP password
    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption
    $mail->Port = 587; // TCP port to connect to

    // Sender and recipient addresses
    $mail->setFrom('xxx.com', 'Your Name'); // Sender's email address and name
    $mail->addAddress('xxx.com', 'Recipient Name'); // Recipient's email address and name

    // Email content
    $mail->isHTML(true); // Set email format to HTML
    $mail->Subject = 'Test Email';
    $mail->Body = 'This is a test email sent using PHPMailer';

    // Send the email
    if ($mail->send()) {
        echo 'Email sent successfully!';
    } else {
        echo 'Error: Email not sent.';
    }
} catch (Exception $e) {
    echo 'Error: ' . $e->getMessage();
}
}                                         // End of function

	echo "1<br>";
	$dummy=func();                        // calling the function
	echo "2<br>";
	exit;
?>

Just throws a 500 Error

Any Ideas?
 

Link to comment
Share on other sites

You require_once and use statements need to be outside the function; they're global functions. You can then use the classes inside a function. So, the instance that works, just put everything after require statements into a function and call it normally.

Link to comment
Share on other sites

  • 2 weeks later...

What you are trying to do is ill advised.  Perhaps if you explained the problem you are trying to solve,  we might be able to provide a better option.

It would help you a good deal, if you understood what namespaces are for.  Namespaces were added in php (as in many other languages) so that library developers could use the same names for classes (or functions) and not have collisions in the global name space.

Use statements are ways of referencing classes that are defined within a namespace.

Then there is autoloading, which is built into PHP.  PHP comes with the option to configure a set of directories that will be searched, should the code reference a class that it does not have loaded.  

There are now standards for how autoloaders can work with namespacing to determine where classes are, and how they are laid out in the filesystem.

As to what you appear to be trying to do, the standard way of wrapping a component library, would be to create your own class, which does all the things you are trying to do with the function.  It could be as simple as the class definition, with a constructor method, and the method you want to call to wrap all the code you've shown.

While it goes against the best practice pattern of Dependency injection, this new class could instantiate phpmailer in it's constructor, and store it in a private variable.  Then you would just have change the code to use the private variable.

 

<?php
// Class MyMailer
namespace MyOrg;

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;    
    
 // Include PHPMailer autoloader or include necessary PHP files
require_once 'PHPMailer/src/PHPMailer.php';
require_once 'PHPMailer/src/SMTP.php';
require_once 'PHPMailer/src/Exception.php';
   
class MyMailer {    

    private $mail;
    private $config = array();
  
    public function __construct(PHPMailer $mail=null) {
        if (!$mail) {
          $this->mail = new PHPMailer(true); // Enable exceptions
          $this->mail->isSMTP();
          $this->mail->Host = 'mail.qss.mgo.mybluehost.me'; // Your SMTP server host
          $this->mail->SMTPAuth = true;
          $this->mail->Username = 'xxxxx'; // Your SMTP username
          $this->mail->Password = 'xxxxx'; // Your SMTP password
          $this->mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; // Enable TLS encryption
          $this->mail->Port = 587; // TCP port to connect to
        }
    }  

    public function send($from, $fromName, $to, $toName, $subject, $body, $isHTML=true) {
      try {

          // Sender and recipient addresses
          $mail->setFrom($from, $fromName); // Sender's email address and name
          $mail->addAddress($to, $toName); // Recipient's email address and name

          // Email content
          $mail->isHTML($isHTML); // Set email format to HTML
          $mail->Subject = $subject;
          $mail->Body = $body;

          // Send the email
          if ($mail->send()) {
              echo 'Email sent successfully!';
          } else {
              echo 'Error: Email not sent.';
          }
      } catch (Exception $e) {
          echo 'Error: ' . $e->getMessage();
      }
    }
  
    public function test() {
        $this-send('xxx.com', 'Your Name', 'xxx.com', 'Recipient Name', 'Test Email', 'This is a test email sent using PHPMailer');  
    }
}

At this point, you can require_once your class where you need it, and you are ready to test with something as simple as this:

require_once('/path/to/MyMailer.php');

use MyOrg\MyMailer;

$mail = new MyMailer();
$mail->test();
Link to comment
Share on other sites

  • Solution

@gizmola, Yes, seems I need to learn about both namespaces and more about classes. I'm an old school layman and really not up to speed. Thanks for the advice.

... I have resolved my issue by just simply not using a function but I understand that I've missed a lot. I mean, for heaven's sake, I'm still on a Macromedia Dreamweaver... ;-). 

So VsCode, and a lot of reading and tutorials it will be when I have time.

Consider the issue closed. Thank you all.

Link to comment
Share on other sites

If you find video material helpful, this channel is an amazing resource: 

 

If you look through the playlist, you can cherry pick individual videos for topics like OOP, Namespaces, Composer etc.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.