phpemailpear

mail with php pear semi-randomly corrupts characters


I'm sending email through pear, but the end result some times has corrupted characters. Despite the email being roughly the same (a couple words change, the recipients e-mail address) the corrupted characters are not always in the same place of the html body. You can see some weird ? characters there. The email is sent as follows through php PEAR:

Example of received on email on gmail account with corrupted body. Some times links get corrupted (it adds a space and/or x0D / %0D character - which is carriage return). Every time, just a word gets corrupted like below. Some times the corrupted character is in the subject, but rarely.

Received: from localhost (some.domain.com [1.2.3.4]) (Authenticated sender: xxx@mydomain.com) by blabla.domain.com (ESMTP) with ESMTPSA for <recipient@gmail.com>; Tue, 25 Jan 2022 01:06:05 +0200 (EET)
From: xxx@mydomain.com
To: recipient@gmail.com
Date: Tue, 25 Jan 2022 01:06:04 +0200
Content-Type: text/html; charset=UTF-8
X-Mailer: PHP/7.x.x
Reply-To: xxx@mydomain.com
Subject: my subject

<html><head><meta http-equiv="Content-Language" content="el"/><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/></head><body>...Content in greek here... όμορφος, πα�
 �άτε εκεί ... content here</body></html>

instead of the word "πατάτε"

php_script_sending_mail.php

                $UserMesssage = "some greek content here which gets corrupted at usually one word";
                $MAILto      = $varEmail;
                $MAILmessage = "<html><head><meta http-equiv=\"Content-Language\" content=\"el\"/><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/></head><body>";
                $MAILmessage .= $UserMesssage;
                $MAILmessage .= "</body></html>";

                mail_new($MAILto, $MAILsubject, $MAILmessage);

fn_mail.php

    function mail_new($to, $subject, $message) {
        require_once "Mail.php";
        
        $from = "xxx@mydomain.com";

        $host = "mailgate.isp.com";
        $username = "xxx@mydomain.com";
        $password = "pass";

        $headers = array ('From' => $from, 'To' => $to, 'Date' => date('r', time()), 'Content-Type' => 'text/html; charset=UTF-8', 'X-Mailer' => 'PHP/'.phpversion(), 'Reply-To' => 'xxx@mydomain.com', 'Subject' => '=?UTF-8?B?'.base64_encode($subject).'?=');
        $smtp = @Mail::factory('smtp', array ('host' => $host, 'auth' => true, 'username' => $username, 'password' => $password));
     
        $mail = @$smtp->send($to, $headers, $message);
     
    }

Both files are saved as UTF-8 without BOM.

Am I doing something wrong? How can I solve this? Thank you in advance.


Solution

  • Install PEAR module Mail/mime and set additional mime headers, i.e. text_charset and html_charset.

    <?php
    
    function mail_new($to, $subject, $message) {
        require_once "Mail.php";
        require_once 'Mail/mime.php';
    
        $from = "xxx@mydomain.com";
    
        $host = "mailgate.isp.com";
        $username = "xxx@mydomain.com";
        $password = "pass";
    
        $headers = array ('From' => $from, 'To' => $to, 'Date' => date('r', time()), 'Content-Type' => 'text/html; charset=UTF-8', 'X-Mailer' => 'PHP/'.phpversion(), 'Reply-To' => 'xxx@mydomain.com', 'Subject' => '=?UTF-8?B?'.base64_encode($subject).'?=');
    
        $mime = new Mail_mime();
        $mime->setHTMLBody($message);
        $mimeparams = array();
        $mimeparams['text_charset'] = "UTF-8";
        $mimeparams['html_charset'] = "UTF-8";
        $message = $mime->get($mimeparams);
        $headers = $mime->headers($headers);
    
        $smtp = @Mail::factory('smtp', array ('host' => $host, 'auth' => true, 'username' => $username, 'password' => $password));
    
        $mail = @$smtp->send($to, $headers, $message);
    
    }
    
    mail_new('xxx@mydomain.com',
             'Test Message',
            '<html><body>Α α, Β β, Γ γ, Δ δ, Ε ε, Ζ ζ, Η η, Θ θ, Ι ι, Κ κ, Λ λ, Μ μ, Ν ν, Ξ ξ, Ο ο, Π π, Ρ ρ, Σ σ/ς, Τ τ, Υ υ, Φ φ, Χ χ, Ψ ψ, Ω ω.</body></html>'
            );