Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP Deprecated: preg_match(): Passing null to parameter #2 ($subject) of type string is deprecated #2926

Closed
SebaOfficial opened this issue Jul 6, 2023 · 3 comments

Comments

@SebaOfficial
Copy link

SebaOfficial commented Jul 6, 2023

Problem description

Whenever I try to send an email using SMTP, I receive this error:

PHP Deprecated:  preg_match(): Passing null to parameter #2 ($subject) of type string is deprecated in vendor/phpmailer/phpmailer/src/PHPMailer.php on line 3576
PHP Deprecated:  preg_match(): Passing null to parameter #2 ($subject) of type string is deprecated in vendor/phpmailer/phpmailer/src/PHPMailer.php on line 5010

Code to reproduce

This is the custom class I'm using to send the email on php8.1

<?php

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


class Mailer{
    protected string $email, $password;
    protected PHPMailer $mail;

    public function __construct(string $email, string $password, string $emailName){
        $this->email = $email;
        $this->password = $password;

        $this->mail = new PHPMailer(true);
        $this->mail->isSMTP();
        $this->mail->Host = $_ENV['EMAIL_HOST'];
        $this->mail->Port = $_ENV['EMAIL_PORT'];
        $this->mail->SMTPAuth = true;
        $this->mail->Username = $email;
        $this->mail->Password = $password;
        $this->mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;

        $this->mail->setFrom($email, $emailName);
        $this->mail->isHTML(true);
    }


    public function send(string $to, string $name, string $subject, string $body, ?string $altBody = null): bool{
        try{

            $this->mail->Subject = $subject;
            $this->mail->Body = $body;
            $this->mail->AltBody = $altBody;
            $this->mail->addAddress($to, $name);
            $this->mail->send();

            return true;

        } catch(Exception $e){
            return false;
        }
    }

}

Suggestion

It may be useful to replace this line with the following code:

return (bool) preg_match('/[\x80-\xFF]/', $text ?? '');

Also, it may be usefult to replace this line eith the following code:

return (bool) preg_match('/^(.{' . (self::MAX_LINE_LENGTH + strlen(static::$LE)) . ',})/m', $str ?? '');

This way both function will return false if either $text or $str are null without causing the deprecation error.

@XL-2000
Copy link

XL-2000 commented Jul 7, 2023

Instead of directly fixing the code, lets see what happens here!
You have not provided sample code of what arguments / data you are using when this problem occurs.
To me, it seems when tracing the PHPMailer code, the problem could be with either your Body or AltBody being null.
This is actually an implementation error and something to be handled at your end.
If you set the Body and AltBody, make sure it is valid and meaningful, to prevent enduser problems.

So maybe it is good to check your own code and see if you are doing the right thing...

@XL-2000
Copy link

XL-2000 commented Jul 7, 2023

Also another point on your code:

$this->mail->send();

            return true;

This seems illogical to me. Since the PHPMailer "send()" function may return FALSE without exceptions indicating something went wrong. I would think returning the actual result of the $this->mail->send(); instead of always TRUE

@Synchro
Copy link
Member

Synchro commented Jul 7, 2023

We can't use ?? in PHPMailer code because it's not supported in versions of PHP that PHPMailer supports.

Generally speaking, this is a developer error - PHPMailer doesn't support null as a message body, subject line, or in various other places where it doesn't make sense. If we were using a later version of PHP, we could enforce this by setting a string type for the $text parameter of has8bitChars(), which would cause a fatal error if you passed null. Because of legacy PHP version support, we can't do that. "Fixing" it in the way you suggest is unlikely to be helpful, because what it will actually do is hide the problem (by returning false) until it causes another problem later on, and that's not the right way to handle such problems. A better solution would be to throw an exception or trigger a fatal error directly, however, that would likely cause all kinds of problems for existing code. So for now, the best solution is to let it be noisy, and make sure that you don't pass in bad data.

In your code, you could fix this by doing this:

$this->mail->Subject = '' . $subject;

Also, as @XL-2000 said, you are discarding any error information when you return false from your catch block, so you're not going to get much feedback when things don't work.

@Synchro Synchro closed this as completed Jul 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants