MirrorMirror
MirrorMirror

Reputation: 188

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: [email protected]) by blabla.domain.com (ESMTP) with ESMTPSA for <[email protected]>; Tue, 25 Jan 2022 01:06:05 +0200 (EET)
From: [email protected]
To: [email protected]
Date: Tue, 25 Jan 2022 01:06:04 +0200
Content-Type: text/html; charset=UTF-8
X-Mailer: PHP/7.x.x
Reply-To: [email protected]
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 = "[email protected]";

        $host = "mailgate.isp.com";
        $username = "[email protected]";
        $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' => '[email protected]', '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.

Upvotes: 0

Views: 146

Answers (2)

Jannes Botis
Jannes Botis

Reputation: 11242

I assume your are using a unix server(or localhost) and have full access to it. I am not sure if the below will solve your issue, give it a try.

Step 1) Find out which locales are installed in your find ubuntu locale list, in terminal:

locale -a

if greek is not installed, try to install it:

sudo locale-gen el_GR
sudo locale-gen el_GR.utf8

To update the locale info:

sudo update-locale 

Step 2) Try to set the locale at the top of your script:

setlocale(LC_CTYPE, "el_GR.utf8");
setlocale(LC_COLLATE, "el_GR.utf8");

You can get the list of locales used by using:

echo setlocale(LC_ALL, 0);

According to the documenation:

  • LC_COLLATE for string comparison, see strcoll()
  • LC_CTYPE for character classification and conversion, for example strtoupper()

Maybe Mail.php is using one of the above functions affected by either LC_CTYPE or LC_COLLATE.

Keep in mind about the warning on the documentation:

The locale information is maintained per process, not per thread. If you are running PHP on a multithreaded server API , you may experience sudden changes in locale settings while a script is running, though the script itself never called setlocale(). This happens due to other scripts running in different threads of the same process at the same time, changing the process-wide locale using setlocale().

References

setlocale php manual

Upvotes: 1

Booboo
Booboo

Reputation: 44213

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 = "[email protected]";

    $host = "mailgate.isp.com";
    $username = "[email protected]";
    $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' => '[email protected]', '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('[email protected]',
         'Test Message',
        '<html><body>Α α, Β β, Γ γ, Δ δ, Ε ε, Ζ ζ, Η η, Θ θ, Ι ι, Κ κ, Λ λ, Μ μ, Ν ν, Ξ ξ, Ο ο, Π π, Ρ ρ, Σ σ/ς, Τ τ, Υ υ, Φ φ, Χ χ, Ψ ψ, Ω ω.</body></html>'
        );

Upvotes: 2

Related Questions