0

刚刚将站点迁移到新服务器。迁移后,php mail() 会发出以文本编码且难以理解的电子邮件。经过一番研究,似乎这可能是base64的问题?我不确定新设置如何导致以前工作的旧电子邮件模板不再工作。旧设置是 Open Solaris,新设置是 Ubuntu 10.04。消息输出:

Content-Type: text/html; charset=utf-8

MIME-Version: 1.0
Mime-Version: 1.0
Content-Transfer-Encoding: BASE64
Message-Id: <20120427211219.E50AE1C83A@li439-167.members.linode.com>
Date: Fri, 27 Apr 2012 17:12:19 -0400 (EDT)
X-pstn-dkim: 0 skipped:not-enabled

PHA+RGVhciBNciBSaWNoYXJkIEVicmlnaHQsPC9wPgoKPHA+VGhhbmsgeW91IHZlcnkgbXVjaCBm

b3Igc3VibWl0dGluZyBhIHNwZWNpYWwgYXBwbGljYXRpb24gdG8gSGFydmFyZApOYXRpb25hbCBN

b2RlbCBVbml0ZWQgTmF0aW9ucyAyMDEzLjwvcD4KCjxwPldlIGFyZSB2ZXJ5IHBsZWFzZWQgdG8g

YXNzaWduIHlvdSB0aGUgZm9sbG93aW5nIHBvc2l0aW9uOjxiciAvPgpBc3NpZ25tZW50OiBMYXJy

eSBQYWdlIChDRU8pPGJyIC8+CkNvbW1pdHRlZTogWmFwYXRhJiMwMzk7cyBDYW1wLCAxOTExPC9w

PgoKPHA+V2UgcmVjZWl2ZWQgYSBsYXJnZSBudW1iZXIgb2YgYXBwbGljYXRpb25zIHRoaXMgeWVh

ciBhbmQgaGF2ZSBkb25lCm91ciB2ZXJ5IGJlc3QgdG8gYWNjb21tb2RhdGUgeW91ciBwcmVmZXJl

bmNlcy4gUGxlYXNlIG5vdGUgdGhhdCBhbGwKYXNzaWdubWVudCBkZWNpc2lvbnMgYXJlIGZpbmFs

LgoKVGhpcyBhc3NpZ25tZW50IGlzIG5vdyByZWZsZWN0ZWQgaW4geW91ciBhY2NvdW50IGluIG91

ciA8YQpocmVmPSJodHRwOi8vbXVuYmFzZS5obm11bi5vcmciPm9ubGluZSByZWdpc3RyYXRpb24g

c3lzdGVtPC9hPiwgd2hpY2gKeW91IGNhbiBhY2Nlc3MgdXNpbmcgdGhlIHNhbWUgbG9nLWluIGFu

ZCBwYXNzd29yZCB5b3UgdXNlZCB0bwpyZWdpc3Rlci4KIFBsZWFzZSB2aXNpdCA8YSBocmVmPSJo

dHRwOi8vd3d3LmhubXVuLm9yZyI+d3d3LmhubXVuLm9yZzwvYT4gZm9yCm1vcmUgaW5mb3JtYXRp

b24gYWJvdXQgeW91ciBjb21taXR0ZWUuPC9wPgo8cD5QbGVhc2Ugbm90ZSB0aGF0IHlvdSBhcmUg

cmVxdWlyZWQgdG8gc3VibWl0IHlvdXIgJDc1IGRlbGVnYXRlIGZlZQpubyBsYXRlciB0aGFuIDEg

RGVjZW1iZXIgMjAxMi4gV2l0aG91dCB0aGUgcGF5bWVudCBvZiB5b3VyIGRlbGVnYXRlCmZlZSwg

d2UgcmVzZXJ2ZSB0aGUgcmlnaHQgdG8gcmVhc3NpZ24geW91ciBwb3NpdGlvbiB0byBhbm90aGVy

CmRlbGVnYXRlLjwvcD4KPHA+SWYgeW91IGhhdmUgYW55IHF1ZXN0aW9ucyBvciBjb25jZXJucywg

cGxlYXNlIGZlZWwgZnJlZSB0byBlbWFpbApvdXIgc3RhZmYgYXQgPGEgaHJlZj0ibWFpbHRvOmlu

Zm9AaG5tdW4ub3JnIj5pbmZvQGhubXVuLm9yZzwvYT4uIFdlCmxvb2sgZm9yd2FyZCB0byBzZWVp

bmcgeW91IGF0IEhOTVVOIDIwMTMgaW4gRmVicnVhcnkhPC9wPgoKCgo8cD5TaW5jZXJlbHksPGJy

IC8+CkdpbGxpYW4gVC4gRmFycmVsbDxiciAvPgpTZWNyZXRhcnktR2VuZXJhbDxiciAvPgpIYXJ2

YXJkIE5hdGlvbmFsIE1vZGVsIFVuaXRlZCBOYXRpb25zIDIwMTM8L3A+Cg==

谢谢您的帮助!长期用户,第一次发帖。希望能更多地回馈 StackOverflow 社区。

编辑:处理邮件发送的 Yii 扩展(?)。

<?php
/**
 * Email class file.
 * 
 * @author Jonah Turnquist <poppitypop@gmail.com>
 * @link http://php-thoughts.cubedwater.com/
 * @version 1.0
 */
class Email extends CApplicationComponent {
/**
 * @var string Type of email.  Options include "text/html" and "text/plain"
 */
public $type = 'text/html';
/**
 * @var string Receiver, or receivers of the mail.
 */
public $to = null;

/**
 * @var string Email subject
 */
public $subject = '';

/**
 * @var string from address
 */
public $from = null;

/**
 * @var string Reply-to address
 */
public $replyTo = null;

/**
 * @var string Return-path address
 */
public $returnPath = null;

/**
 * @var string Carbon Copy
 *
 * List of email's that should receive a copy of the email.
 * The Recipient WILL be able to see this list
 */
public $cc = null;

/**
 * @var string Blind Carbon Copy
 *
 * List of email's that should receive a copy of the email.
 * The Recipient WILL NOT be able to see this list
 */
public $bcc = null;

/**
 * @var string Main content
 */
public $message = '';

/**
 * @var string Delivery type.  If set to 'php' it will use php's mail() function, and if set to 'debug'
 * it will not actually send it but output it to the screen
 */
public $delivery = 'php';

/**
 * @var string language to encode the message in (eg "Japanese", "ja", "English", "en" and "uni" (UTF-8))
 */
public $language= 'uni';

/**
 * @var string the content-type of the email
 */
public $contentType= 'utf-8';

/**
 * @var string The view to use as the content of the email, as an alternative to setting $this->message.
 * Must be located in application.views.email directory.  This email object is availiable within the view
 * through $email, thus letting you define things such as the subject within the view (helps maintain 
 * seperation of logic and output).
 */
public $view = null;

/**
 * @var array Variable to be sent to the view.
 */
public $viewVars = null;    

/**
 * @var string The layout for the view to be imbedded in. Must be located in
 * application.views.email.layouts directory.  Not required even if you are using a view
 */
public $layout = null;

/**
 * @var integer line length of email as per RFC2822 Section 2.1.1
 */
public $lineLength = 70;

public function __construct() {
    Yii::setPathOfAlias('email', dirname(__FILE__).'/views');
}

  /**
   * Model United Nations Specific sending function.
   */
  public function quick($subject, $view, $to, $info=null, $cc=null) {
$this->subject = $subject;
$this->from = 'ADDRESS REMOVED';
$this->to = $to;
if ($cc) $this->cc = $cc;
$this->bcc = 'ADDRESS REMOVED';
$this->view = $view;
$this->send($info);
  }

/**
 * Sends email.
 * @param mixed the content of the email, or variables to be sent to the view.
 * If not set, it will use $this->message instead for the content of the email
 */
public function send($arg1=null) {
    if ($this->view !== null) {
        if ($arg1 == null)
            $vars = $this->viewVars;
        else
            $vars = $arg1;

        $view = Yii::app()->controller->renderPartial('application.views.email.'.$this->view, array_merge($vars, array('email'=>$this)), true);
        if ($this->layout === null) {
            $message = $view;
        } else {
            $message = Yii::app()->controller->renderPartial('application.views.email.layouts.'.$this->layout, array('content'=>$view), true);
        }
    } else {
        if ($arg1 === null) {
            $message = $this->message;
        } else {
            $message = $arg1;
        }
    }

    //process 'to' attribute
    $to = $this->processAddresses($this->to);
    return $this->mail($to, $this->subject, $message);
}

private function mail($to, $subject, $message) {
    switch ($this->delivery) {
        case 'php':
            $message = wordwrap($message, $this->lineLength);
    mb_internal_encoding("UTF-8");
            mb_language($this->language);
            return mb_send_mail($to, $subject, $message, implode("\r\n", $this->createHeaders()), '-fmunbase@ADDRESS.org');
        case 'debug':
            $debug = Yii::app()->controller->renderPartial('email.debug',
                    array_merge(compact('to', 'subject', 'message'), array('headers'=>$this->createHeaders())),
                    true);
            Yii::app()->user->setFlash('email', $debug);
            break;
    }
}
private function createHeaders() {
    $headers = array();

    //maps class variable names to header names
    $map = array(
        'from' => 'From',
        'cc' => 'Cc',
        'bcc' => 'Bcc',
        'replyTo' => 'Reply-To',
        'returnPath' => 'Return-Path',
    );
    foreach ($map as $key => $value) {
        if (isset($this->$key))
            $headers[] = "$value: {$this->processAddresses($this->$key)}";
    }
    $headers[] = "Content-Type: {$this->type}; charset=".$this->contentType;
    $headers[] = "MIME-Version: 1.0";

    return $headers;
}
private function processAddresses($addresses) {
    return (is_array($addresses)) ? implode(', ', $addresses) : $addresses;
}
}
4

1 回答 1

0

原来额外的线路回报是罪魁祸首。原始(错误版本)消息头摘录如下:

X-PHP-Originating-Script: 0:Email.php
From: Harvard National Model United Nations 2013 <info@hnmun.org>

Content-Type: text/html; charset=UTF-8

Mime-Version: 1.0

Content-Transfer-Encoding: BASE64

并且是由扩展控件中的 implode 命令引起的:

private function mail($to, $subject, $message) {
switch ($this->delivery) {
    case 'php':
        $message = wordwrap($message, $this->lineLength);
mb_internal_encoding("UTF-8");
        mb_language($this->language);
        return mb_send_mail($to, $subject, $message, implode("\r\n", $this->createHeaders()), '-fmunbase@ADDRESS.org');
    case 'debug':
        $debug = Yii::app()->controller->renderPartial('email.debug',
                array_merge(compact('to', 'subject', 'message'), array('headers'=>$this->createHeaders())),
                true);
        Yii::app()->user->setFlash('email', $debug);
        break;
}

原来它需要一个参数implode("\n", $this->createHeaders())而不是implode("\r\n", $this->createHeaders()) 与新版本的 PHP 或新操作系统有关的东西?谢谢大家的帮助!

于 2012-04-29T05:47:55.270 回答