PHP邮件:链接中的正常字符正在被替换


PHP mail: normal characters from link are being replaced

我使用一个简单的脚本发送测试电子邮件:

 $sql = "SELECT name, update_url FROM `accounts` WHERE `subscription_id` = '4692'";
 $res = mysqli_query($con, $sql);
 $row =  mysqli_fetch_assoc($res);
 $name = $row["name"];
 $updateUrl = $row["update_url"];
 echo $updateUrl;
 $subject = 'Subscription Payment Has Failed';
 $message = 'Hi ' . $name . ',
 Your subscription payment has failed. You can use the link below to update your payment information if needed:
' . $updateUrl .'
Cheers,
test name';
        $headers = 'From: test ' . "'r'n";
        $headers .= "Content-type: text/plain; charset='"UTF-8'"; format=flowed 'r'n";
        $headers .= "Mime-Version: 1.0 'r'n";
        $headers .= "Content-Transfer-Encoding: quoted-printable 'r'n";
        mail($email, $subject, $message, $headers);

我遇到的问题是,$updateUrl即使正确存储在数据库中,也会通过邮件被破坏。

更确切地说:在数据库中,它是这样存储的:https://test.testsite.com/sub/update?user=406530&订阅=4692&hash=01d75f25e599e3c842ea5288f47e

在发送的邮件中,收到的邮件是这样的:https://test.testsite.com/sub/update?user@6530&订阅F92&散列d75f25e599e3c842ea5288f47e

请注意,'=40'替换为'@','=46'替换为'F','=01'替换为空格。

是什么原因导致的,这是什么类型的字符表示/编码?

值得一提的是,当以内容类型为text/HTML/

的HTML发送时,这种情况仍然会发生

这是RFC2045引用的可打印编码,完全正常。问题是,您声明了一个内容传输编码,但没有对要匹配的内容进行编码,所以任何看起来像QP编码的内容都会被错误地解码。您需要将它应用于整个MIME部分(在您的情况下是整个消息),而不仅仅是URL,使用quoted_printable_encode,如下所示:

mail($email, $subject, quoted_printable_encode($message), $headers);

调用它也会将文本包装为76个字符行,但这不会影响所传递消息的外观,因为编码是无损的。

如果您没有使用PHPMailer,请不要将您的问题标记为PHPMailler。

您必须使用quoted_printable_encode:

PHPMailer使用此代码对消息的每一行进行编码(如果使用"引用可打印"编码:

public function encodeQP($string, $line_max = 76)
{
    // Use native function if it's available (>= PHP5.3)
    if (function_exists('quoted_printable_encode')) {
        return quoted_printable_encode($string);
    }
    // Fall back to a pure PHP implementation
    $string = str_replace(
        array('%20', '%0D%0A.', '%0D%0A', '%'),
        array(' ', "'r'n=2E", "'r'n", '='),
        rawurlencode($string)
    );
    return preg_replace('/[^'r'n]{' . ($line_max - 3) . '}[^='r'n]{2}/', "$0='r'n", $string);
}

您需要对正在发送的消息执行此操作
至少。

查看PHPMailer正在使用的代码。发送电子邮件是一门黑色艺术。