quoted_printable_encode

(PHP 5 >= 5.3.0, PHP 7, PHP 8)

quoted_printable_encode将 8 位字符串转换为 Quoted-Printable 字符串

说明

quoted_printable_encode(string $string): string

根据 » RFC2045 第 6.7 节返回一个 Quoted-Printable 字符串。

此函数类似于 imap_8bit(),只是它不需要 IMAP 模块来工作。

参数

string

输入字符串。

返回值

返回编码后的字符串。

示例

示例 #1 quoted_printable_encode() 示例

<?php

$encoded
= quoted_printable_encode('Möchten Sie ein paar Äpfel?');

var_dump($encoded);
var_dump(quoted_printable_decode($encoded));
?>

以上示例将输出

string(37) "M=C3=B6chten Sie ein paar =C3=84pfel?"
string(29) "Möchten Sie ein paar Äpfel?"

参见

添加注释

用户贡献的注释 6 个注释

jurgen at edesign dot nl
9 年前
PHP 的原生实现和 ericth at NOSPAM dot pennyworth dot com 的函数(如下)都包含一个功能/错误(SMTP 使用不匹配),我已经在我的调整中解决了。

此错误会导致包含句点字符的文本在通过这些函数传递后,最终产生以句点字符开头的编码行,当它通过 SMTP 传输时,该行上的第一个句点字符将被丢弃。

解决方法:在句点字符之前添加(另一个)前导“.”,当编码后句点字符将成为行上的第一个字符。

参见 http://stackoverflow.com/a/13949483: "这是一种低级传输层的脏东西... SMTP 是最有可能的罪魁祸首(参见邮件函数文档中的谨慎提醒),但也可能存在其他类似行为的低级机制。例如,如果您调整了 sendmail_path 设置或使用了有问题的 sendmail 程序,您可能会遇到类似的问题。"

<?php
define
('PHP_QPRINT_MAXL', 75);

function
leading_dot_fixed_php_quot_print_encode($str)
{
$lp = 0;
$ret = '';
$hex = "0123456789ABCDEF";
$length = strlen($str);
$str_index = 0;

while (
$length--) {
if (((
$c = $str[$str_index++]) == "\015") && ($str[$str_index] == "\012") && $length > 0) {
$ret .= "\015";
$ret .= $str[$str_index++];
$length--;
$lp = 0;
} else {
if (
ctype_cntrl($c)
|| (
ord($c) == 0x7f)
|| (
ord($c) & 0x80)
|| (
$c == '=')
|| ((
$c == ' ') && ($str[$str_index] == "\015")))
{
if ((
$lp += 3) > PHP_QPRINT_MAXL)
{
$ret .= '=';
$ret .= "\015";
$ret .= "\012";
$lp = 3;
}
$ret .= '=';
$ret .= $hex[ord($c) >> 4];
$ret .= $hex[ord($c) & 0xf];
}
else
{
if ((++
$lp) > PHP_QPRINT_MAXL)
{
$ret .= '=';
$ret .= "\015";
$ret .= "\012";
$lp = 1;
}
$ret .= $c;
if(
$lp == 1 && $c == '.') {
$ret .= '.';
$lp++;
}
}
}
}

return
$ret;
}

?>
arnaudv6
12 年前
人们希望知道并清楚地了解 RFC2045 规定一行不能超过 75 个字符。
因此,quoted_printable_encode() 在此限制处分割行。
Thorsten Glaser
13 年前
两个错误

1) 您的换行符是错误的

$linebreak = "\r\n";

2) 没有空格的行的继续是错误的

/*
* 空格后的文本必须
* 重新读取(+ 由于
* 编码过程中空格后的任何额外的字符
* 而产生的任何额外的字符)
*
* 此外,不要从 0 开始,如果整行中 *没有*
* 空格
*/
if (($i + $addtl_chars) > $whitesp_diff) {
$output .= substr($cur_conv_line, 0,
(strlen($cur_conv_line) - $whitesp_diff)) .
$linebreak;
$i = $i - $whitesp_diff + $addtl_chars;
} else {
/* 发出继续 --mirabilos */
$output .= $cur_conv_line .
'=' . $linebreak;
}
ericth at NOSPAM dot pennyworth dot com
12 年前
我已将 PHP 5.3.8 中的 quoted_printable_encode 函数重新编写为 PHP,以便与 PHP < 5.3 一起使用。已在 PHP 5.2.11 上测试。

<?php
define
('PHP_QPRINT_MAXL', 75);

function
php_quot_print_encode($str)
{
$lp = 0;
$ret = '';
$hex = "0123456789ABCDEF";
$length = strlen($str);
$str_index = 0;

while (
$length--) {
if (((
$c = $str[$str_index++]) == "\015") && ($str[$str_index] == "\012") && $length > 0) {
$ret .= "\015";
$ret .= $str[$str_index++];
$length--;
$lp = 0;
} else {
if (
ctype_cntrl($c)
|| (
ord($c) == 0x7f)
|| (
ord($c) & 0x80)
|| (
$c == '=')
|| ((
$c == ' ') && ($str[$str_index] == "\015")))
{
if ((
$lp += 3) > PHP_QPRINT_MAXL)
{
$ret .= '=';
$ret .= "\015";
$ret .= "\012";
$lp = 3;
}
$ret .= '=';
$ret .= $hex[ord($c) >> 4];
$ret .= $hex[ord($c) & 0xf];
}
else
{
if ((++
$lp) > PHP_QPRINT_MAXL)
{
$ret .= '=';
$ret .= "\015";
$ret .= "\012";
$lp = 1;
}
$ret .= $c;
}
}
}

return
$ret;
}

?>
marcus at synchromedia dot co dot uk
7 年前
请注意,此函数返回使用 Windows / RFC822 CRLF 换行符的 Quoted-Printable 字符串。如果将此函数的输出传递给 mail(),则可能需要先将其换行符转换为 Unix LF 样式。
tzangerl [dot] pdc {dot} kth dot se
14 年前
一个用于对输入字符串进行 QP 编码的函数(为 PHP < 5.3 编写的),并且
同时进行换行,以避免根据 SpamAssassin 的 MIME QP LONG LINE 规则进行分类。感谢 Matt Jeffers 指出以下 quoted_printable 脚本中的错误!

<?php
function quoted_printable_encode($input, $line_max = 75) {
$hex = array('0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F');
$lines = preg_split("/(?:\r\n|\r|\n)/", $input);
$linebreak = "=0D=0A=\r\n";
/* the linebreak also counts as characters in the mime_qp_long_line
* rule of spam-assassin */
$line_max = $line_max - strlen($linebreak);
$escape = "=";
$output = "";
$cur_conv_line = "";
$length = 0;
$whitespace_pos = 0;
$addtl_chars = 0;

// iterate lines
for ($j=0; $j<count($lines); $j++) {
$line = $lines[$j];
$linlen = strlen($line);

// iterate chars
for ($i = 0; $i < $linlen; $i++) {
$c = substr($line, $i, 1);
$dec = ord($c);

$length++;

if (
$dec == 32) {
// space occurring at end of line, need to encode
if (($i == ($linlen - 1))) {
$c = "=20";
$length += 2;
}

$addtl_chars = 0;
$whitespace_pos = $i;
} elseif ( (
$dec == 61) || ($dec < 32 ) || ($dec > 126) ) {
$h2 = floor($dec/16); $h1 = floor($dec%16);
$c = $escape . $hex["$h2"] . $hex["$h1"];
$length += 2;
$addtl_chars += 2;
}

// length for wordwrap exceeded, get a newline into the text
if ($length >= $line_max) {
$cur_conv_line .= $c;

// read only up to the whitespace for the current line
$whitesp_diff = $i - $whitespace_pos + $addtl_chars;

/* the text after the whitespace will have to be read
* again ( + any additional characters that came into
* existence as a result of the encoding process after the whitespace)
*
* Also, do not start at 0, if there was *no* whitespace in
* the whole line */
if (($i + $addtl_chars) > $whitesp_diff) {
$output .= substr($cur_conv_line, 0, (strlen($cur_conv_line) -
$whitesp_diff)) . $linebreak;
$i = $i - $whitesp_diff + $addtl_chars;
} else {
$output .= $cur_conv_line . $linebreak;
}

$cur_conv_line = "";
$length = 0;
$whitespace_pos = 0;
} else {
// length for wordwrap not reached, continue reading
$cur_conv_line .= $c;
}
}
// end of for

$length = 0;
$whitespace_pos = 0;
$output .= $cur_conv_line;
$cur_conv_line = "";

if (
$j<=count($lines)-1) {
$output .= $linebreak;
}
}
// end for

return trim($output);
}
// end quoted_printable_encode
?>
To Top