Search code examples
phpmailer

PHPMailer Debug messages


I'm using PHPMailer and I would like to save in my DB some debug info.

The code below shows how to save debug info when using an SMTP server like below:

mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->SMTPDebug = 2; //Alternative to above constant
$mail->isSMTP();  // tell the class to use SMTP
$mail->SMTPAuth   = true;                // enable SMTP authentication
$mail->Port       = 25;                  // set the SMTP port
$mail->Host       = "mail.yourhost.com"; // SMTP server
$mail->Username   = "[email protected]"; // SMTP account username
$mail->Password   = "your password";     // SMTP account password

According to the PHPMailer documentation SMTPDebug has 4 levels.

SMTP::DEBUG_OFF (0): Disable debugging (you can also leave this out completely, 0 is the default).
SMTP::DEBUG_CLIENT (1): Output messages sent by the client.
SMTP::DEBUG_SERVER (2): as 1, plus responses received from the server (this is the most useful setting).
SMTP::DEBUG_CONNECTION (3): as 2, plus more information about the initial connection - this level can help diagnose STARTTLS failures.
SMTP::DEBUG_LOWLEVEL (4): as 3, plus even lower-level information, very verbose, don't use for debugging SMTP, only low-level problems.

When I use level 2 I get Client and Server responses logged to the screen.

Is there a way to have only Server responses logged? I do not want to save Clients request too as it may have some sensitive data (The email content sent itself).


Solution

  • Yes. You can inject a closure that captures the debug output and writes it to your DB. There is an example in the docs:

    It might be something like this (including filtering out client messages):

    $mail->Debugoutput = function($str, $level) use ($db) {
        if (strpos($str, 'CLIENT -> SERVER') === false) {
            mysqli_query($db, "INSERT INTO maildebug SET level = '".mysqli_real_escape_string($db, $level)."', message = '".mysqli_real_escape_string($db, $str)."'");
        }
    };
    

    A somewhat tidier option would be to accumulate all the debug output in a temporary variable, and only write it to the DB if there is a problem.