PHP邮件:正在替换链接中的普通字符

时间:2016-03-29 15:19:43

标签: php encoding

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

 $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即使它正确存储在数据库中,也会通过邮件发送。

更确切地说: 在DB中,它存储如下: https://test.testsite.com/sub/update?user=406530&subscription=4692&hash=01d75f25e599e3c842ea5288f47e

在发送的邮件中收到的内容如下: https://test.testsite.com/sub/update?user@6530&subscriptionF92&hash d75f25e599e3c842ea5288f47e

请注意,'=''代替'@','= 46'代替'F','= 01'代替空格。

什么可能导致这种情况,这是什么类型的字符表示/编码?

值得一提的是,当发送为内容类型为text / html

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

2 个答案:

答案 0 :(得分:3)

这是RFC2045 quoted-printable encoding,完全正常。问题在于您声明了内容传输编码,但没有对内容进行编码以匹配,因此任何看起来像QP编码的内容都会被错误地解码。您需要使用quoted_printable_encode将其应用于整个MIME部分(在您的情况下是整个消息),而不仅仅是URL,使用http://www.hascode.com/2011/09/rest-assured-vs-jersey-test-framework-testing-your-restful-web-services/

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

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

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

答案 1 :(得分:1)

您必须使用quoted_printable_encode

PHPMailer正在使用此代码对邮件的每一行进行编码(如果它使用'quoted-printable'编码:

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正在使用的代码。发送电子邮件是一种黑色艺术。