森林之原
二月 04, 2012, 03:44:35 am *
歡迎光臨, 訪客. 請先 登入註冊一個帳號.

請輸入帳號, 密碼以及預計登入時間
新聞: 官方釋出 SMF 2.0 beta。繁體中文已經完成。請到 SMF 的版面下載測試。如有問題請通知。
 
   首頁   說明 搜尋 日曆 登入 註冊  
頁: [1] 2   向下
  寄送主題  |  列印  
作者 主題: [修改]電子郵件 標題的中文是亂碼  (閱讀 27087 次)
0 會員 以及 1 訪客 正在閱讀本篇主題.
Owl
初學者
*
離線 離線

文章: 46


« 於: 八月 31, 2005, 01:44:32 pm »

我從 zencart 送出一些測試 email,但是收到後發現,標題的中文部分是亂碼,email 的本文則是英文,中文都很好。我把 email client 的 character encoding 換成 big5 也是看到亂碼,顯然這些碼不是 big5 也不是 utf-8,我的 zencart 用的是 utf-8,不知道這是哪裡出錯?
« 最後編輯時間: 十月 24, 2005, 11:34:14 am 由 seethrou » 向版主檢舉   已記錄
plone
見習生
**
離線 離線

文章: 77


« 回覆文章 #1 於: 八月 31, 2005, 09:06:27 pm »

請參考頂置文章「已知的中文問題」
我想目前的解決方法是把store 的名稱及相關的語文定義(電郵主旨改為英文)
向版主檢舉   已記錄
Owl
初學者
*
離線 離線

文章: 46


« 回覆文章 #2 於: 九月 20, 2005, 01:35:38 pm »

上網找了一陣,pear.php.net 與 phpguru.org 都提到 HTML mime header 加碼的問題與方法
因為我在 zencart 裏看不到,它在哪裡做 header 的加碼,而我實在需要中文標題,所以直接在 email.php 裏加了幾行,對我來講可以用, 如下。

1 在 class email 之前加入以下的 function。
function encode_str($str)
{
   $charset = constant('CHARSET');
   preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $str, $matches);
       foreach ($matches[1] as $value)
   {
      $replacement = preg_replace('/([\x80-\xFF])/e', '"=" . rtoupper(dechex(ord("\1")))', $value);
      $str = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $str);
   }
   return $str;
}   

2 在 function send 裏加入以下的幾行
/**
 * Sends the mail.
 */
function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '')
{
   ....
   ....
       if (!isset($xtra_headers)) {
        $xtra_headers = array();
      }
//die(EMAIL_TRANSPORT);
     /*-加-- begin ---*/
      $subject = encode_str($subject);
      $from = encode_str($from);
      $to = encode_str($to);

     /*-加-- end ---*/
      switch(EMAIL_TRANSPORT) {
      case ('smtp'):
        $headers_list  = 'From: ' . $from . $this->lf;
        $headers_list .= 'To: ' . $to . $this->lf;
   ....
   ....
}
向版主檢舉   已記錄
plone
見習生
**
離線 離線

文章: 77


« 回覆文章 #3 於: 九月 20, 2005, 09:14:13 pm »



1 在 class email 之前加入以下的 function。
function encode_str($str)
{
   $charset = constant('CHARSET');
   preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $str, $matches);
    foreach ($matches[1] as $value)
   {
      $replacement = preg_replace('/([\x80-\xFF])/e', '"=" . rtoupper(dechex(ord("\1")))', $value);
      $str = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $str);
   }
   return $str;
}



請問是這樣嗎?
  class email {
    var $html;
    var $text;
    var $output;
    var $html_text;
    var $html_images;
    var $image_types;
    var $build_params;
    var $attachments;
    var $headers;

    function email($headers = '') {
      if ($headers == '') $headers = array();

      $this->html_images = array();
      $this->headers = array();

      if (EMAIL_LINEFEED == 'CRLF') {
        $this->lf = "\r\n";
      } else {
        $this->lf = "\n";
      }
//新增---為解決中文標題問題--開始
    function encode_str($str)
    {
       $charset = constant('CHARSET');
       preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $str, $matches);
           foreach ($matches[1] as $value)
       {
          $replacement = preg_replace('/([\x80-\xFF])/e', '"=" . rtoupper(dechex(ord("\1")))', $value);
          $str = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $str);
       }
       return $str;
    }   
//新增---為解決中文標題問題--結束

還是這樣:

//新增---為解決中文標題問題--開始
    function encode_str($str)
    {
       $charset = constant('CHARSET');
       preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $str, $matches);
           foreach ($matches[1] as $value)
       {
          $replacement = preg_replace('/([\x80-\xFF])/e', '"=" . rtoupper(dechex(ord("\1")))', $value);
          $str = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $str);
       }
       return $str;
    }   
//新增---為解決中文標題問題--結束
  class email {
    var $html;
    var $text;
    var $output;
    var $html_text;
    var $html_images;
    var $image_types;
    var $build_params;
    var $attachments;
    var $headers;

    function email($headers = '') {
      if ($headers == '') $headers = array();

      $this->html_images = array();
      $this->headers = array();

      if (EMAIL_LINEFEED == 'CRLF') {
        $this->lf = "\r\n";
      } else {
        $this->lf = "\n";
      }
« 最後編輯時間: 九月 20, 2005, 09:26:35 pm 由 plone » 向版主檢舉   已記錄
Owl
初學者
*
離線 離線

文章: 46


« 回覆文章 #4 於: 九月 21, 2005, 01:32:50 am »

我是用第二個方式.
向版主檢舉   已記錄
Owl
初學者
*
離線 離線

文章: 46


« 回覆文章 #5 於: 十月 04, 2005, 06:03:19 pm »

發覺有些客戶不能讀utf-8信件,可能是設定的問題,也有可能是信箱不支持utf-8。
所以參考了前輩們的討論,決定將 email 改為 big5。
測試平台:windows 2000, php 5.0.3, apache 2.0。

用 phpMailer for zencart 如下:

1. Install phpMailer for zencart.

2. 在 chinese_tc_utf-8.php 加一行,將網頁與郵件的 charset 分開。

-----
-----
// charset for web pages and emails
define('CHARSET', 'utf-8');
define('EMAIL_CHARSET', 'big5');
-----
-----

以下都是修改 function_phpmailer.php

3. 在 73行左右,修改如下。

function phpmailer($from_email_address, $from_email_name, $to_email_address, $to_name, $email_reply_to_address, $email_reply_to_name, $email_html, $customers_email_format, $email_subject, $email_html, $text, $module) {

 //--- add begin -----
        $web_charset = constant('CHARSET');
       $email_charset = constant('EMAIL_CHARSET');
      
         if ($web_charset != $email_charset)
      {
            $email_subject  = iconv($web_charset,$email_charset,$email_subject);
            $from_email_name = iconv($web_charset,$email_charset,$from_email_name);
            $to_name  = iconv($web_charset,$email_charset,$to_name);
            $text = iconv($web_charset,$email_charset,$text);
      }
 //--- add end --------

4. CHARSET 改為 EMAIL_CHARSET。

    $mail->CharSet =  (defined('CHARSET')) ? CHARSET : "iso-8859-1";
   
    改為
   
    $mail->CharSet =  (defined('EMAIL_CHARSET')) ? EMAIL_CHARSET : "iso-8859-1";

   

5. 修改 $email_reply_to_name。

  將這幾行
   
  $email_reply_to_address=($email_reply_to_address) ? $email_reply_to_address : EMAIL_FROM;
  $email_reply_to_name   =($email_reply_to_name) ? $email_reply_to_name : STORE_NAME;
  $mail->AddReplyTo($email_reply_to_address, $email_reply_to_name);
 
   改為
   
  $email_reply_to_address=($email_reply_to_address) ? $email_reply_to_address : EMAIL_FROM;
  $email_reply_to_name   =($email_reply_to_name) ? $email_reply_to_name : STORE_NAME;
  if ($web_charset != $email_charset)
  {
        $email_reply_to_name = iconv($web_charset,$email_charset,$email_reply_to_name);
  }
  $mail->AddReplyTo($email_reply_to_address, $email_reply_to_name);

6. 請注意,admin 那邊的 function_phpmailer.php 也一樣要改。


不用 phpMailer for zencart 的話,就用下面的。

1. 在 chinese_tc_utf-8.php 加一行,將網頁與郵件的 charset 分開。
-----
-----
// charset for web pages and emails
define('CHARSET', 'utf-8');
define('EMAIL_CHARSET', 'big5');
-----
-----

2. 從原始的 email.php 開始。


3. email.php 73 行左右 CHARSET 改為 EMAIL_CHARSET。
      $this->build_params['html_charset'] = constant('EMAIL_CHARSET');
      $this->build_params['text_charset'] = constant('EMAIL_CHARSET');

4. 改 email.php  function add_text。
   
    function add_text($text = '')
    {
      //---- email in different charset begin -----
        $web_charset = constant('CHARSET');
       $email_charset = constant('EMAIL_CHARSET');

      if ($web_charset != $email_charset)
      {
         $text  = iconv($web_charset,$email_charset,$text);
      }
        //----- email in different charset end -----
      $this->text = zen_convert_linefeeds(array("\r\n", "\n", "\r"), $this->lf, $text);
    }

5. 改 email.php function add_html。

    function add_html($html, $text = NULL, $images_dir = NULL)
    {
      //--- email in different charset begin -----
        $web_charset = constant('CHARSET');
       $email_charset = constant('EMAIL_CHARSET');

      if ($web_charset != $email_charset)
      {
         $text  = iconv($web_charset,$email_charset,$text);
      }
        //--- email in different charset end -----

      $this->html = zen_convert_linefeeds(array("\r\n", "\n", "\r"), '
', $html);
      $this->html_text = zen_convert_linefeeds(array("\r\n", "\n", "\r"), $this->lf, $text);

      if (isset($images_dir)) $this->find_html_images($images_dir);
    }

6. 在 email.php 裏 function send 之前,加入 function encode_str_Q。這是 phpMailer 的方法,比較對。

 //--- add header encode -- start
   function encode_str_Q($str, $email_charset)
   {
      if ( $str == '') return $str;
        $encoded = preg_replace("[\r\n]", "", $str);
        $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
                  "'='.sprintf('%02X', ord('\\1'))", $encoded);
        $encoded = str_replace(" ", "_", $encoded);
        $encoded = preg_replace('/^(.*)$/m', " =?". $email_charset."?Q?\\1?=", $encoded);
        return $encoded;
   }
 // --- add header encode -- end */
 
 7. 在 email.php,function send 裏加入這幾行。
 
     function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '')
    {
      //--- convert and encode begin--------
        $web_charset = constant('CHARSET');
       $email_charset = constant('EMAIL_CHARSET');
      
         if ($web_charset != $email_charset)
      {
            $subject  = iconv($web_charset,$email_charset,$subject);
            $from_name = iconv($web_charset,$email_charset,$from_name);
            $to_name  = iconv($web_charset,$email_charset,$to_name);
      }

      $subject    = $this->encode_str_Q($subject, $email_charset);
      $from_name   = $this->encode_str_Q($from_name,  $email_charset);
      $to_name   = $this->encode_str_Q($to_name, $email_charset);

      //--- convert and encode end-----------
     
      $to = (($to_name != '') ? '"' . $to_name . '" <' . $to_addr . '>' : $to_addr);
      $from = (($from_name != '') ? '"' . $from_name . '" <' . $from_addr . '>' : $from_addr);
      -----
      -----
      -----
 
向版主檢舉   已記錄
plone
見習生
**
離線 離線

文章: 77


« 回覆文章 #6 於: 十月 06, 2005, 10:22:03 pm »

很受用,解決了我的問題。
我之前的問題是:text,及html的信件內容都正常,只有寄件人(店名為中文時)、收件人及信件主旨為亂碼

我不用 phpMailer for zencart ,
Owl提供的做法,3、4、5的步驟省略,只做1、2、6、7的步驟

就OK了

不過phpMailer for zencart是什麼?zencart官方釋出的程式嗎?還是非官方所釋出的程式?可否請解說一下,謝謝!
« 最後編輯時間: 十月 06, 2005, 10:42:30 pm 由 plone » 向版主檢舉   已記錄
Owl
初學者
*
離線 離線

文章: 46


« 回覆文章 #7 於: 十月 07, 2005, 10:02:34 am »

phpMailer for zencart 是 seethrou 所提供的。
請參考主題: " 網站為utf-8編碼,是否可以將寄出郵件的編碼改成big5? "   

另外關於上面改法,請注意 admin 那邊的 chinese_tc_utf-8.php 也要改!
不然的話它不知如何編碼,如果願意的話,將
    constant('EMAIL_CHARSET')
改成
   (defined('EMAIL_CHARSET')) ? EMAIL_CHARSET : CHARSET;
可能比較安全。不週之處請見諒。
« 最後編輯時間: 十月 07, 2005, 03:40:34 pm 由 Owl » 向版主檢舉   已記錄
ssbrianhk
初學者
*
離線 離線

文章: 22


« 回覆文章 #8 於: 十月 15, 2005, 11:48:27 am »

謝謝各位詳盡的解釋,text 的電郵已成功轉成 big 5  smiley01_037
但 html 的電郵內容仍然是 utf-8,請問是否可以把 html mail 的內容也轉為 big 5 呢?
向版主檢舉   已記錄
Owl
初學者
*
離線 離線

文章: 46


« 回覆文章 #9 於: 十月 15, 2005, 11:05:56 pm »

html email 也轉 big5

在 email.php 裏  add_html 加一行,如下:

    function add_html($html, $text = NULL, $images_dir = NULL)
    {
      //--- email in different charset begin -----
        $web_charset = constant('CHARSET');
       $email_charset = constant('EMAIL_CHARSET');

      if ($web_charset != $email_charset)
      {
         $text  = iconv($web_charset,$email_charset,$text);
        $html = iconv($web_charset,$email_charset,$html);
      }
        //--- email in different charset end -----

      $this->html = zen_convert_linefeeds(array("\r\n", "\n", "\r"), '
', $html);
      $this->html_text = zen_convert_linefeeds(array("\r\n", "\n", "\r"), $this->lf, $text);

      if (isset($images_dir)) $this->find_html_images($images_dir);
    }


如果用 phpMailer for zencart,如下:

在  function_phpmailer.php 73行左右,修改如下。 admin 那邊也一樣。

function phpmailer($from_email_address, $from_email_name, $to_email_address, $to_name, $email_reply_to_address, $email_reply_to_name, $email_html, $customers_email_format, $email_subject, $email_html, $text, $module) {

 //--- add begin -----
        $web_charset = constant('CHARSET');
       $email_charset = constant('EMAIL_CHARSET');
     
         if ($web_charset != $email_charset)
      {
            $email_subject  = iconv($web_charset,$email_charset,$email_subject);
            $from_email_name = iconv($web_charset,$email_charset,$from_email_name);
            $to_name  = iconv($web_charset,$email_charset,$to_name);
            $text = iconv($web_charset,$email_charset,$text);
            $email_html =  iconv($web_charset,$email_charset,$email_html);
      }
 //--- add end --------

還有 html email template 裏的 charset=iso-8859-1 好像可以不管,至少我試了,沒問題。
不放心的話,可以用 substr_replace 把它換掉。比如:

      if ($web_charset != $email_charset)
      {
         $text  = iconv($web_charset,$email_charset,$text);
         $idx = strpos($html,"charset=iso-8859-1");
         $html = substr_replace($html,$email_charset,$idx + 8,10);

         $html  = iconv($web_charset,$email_charset,$html);
      }



向版主檢舉   已記錄
Owl
初學者
*
離線 離線

文章: 46


« 回覆文章 #10 於: 十月 28, 2005, 12:36:32 am »

剛剛發現, web site 用 utf-8 而想送 big5 email,chinese_tc_utf-8.php 有一個地方也需要改。

如果主機支援 'zh_TW.UTF-8',
@setlocale(LC_TIME, 'zh_TW.Big5'); ---- 改成 ---> @setlocale(LC_TIME, 'zh_TW.UTF-8'); .

如果主機支援 'zh_TW.UTF-8',
define('DATE_FORMAT_LONG', '%A, %d日%m月%Y年 '); ---改成 -->define('DATE_FORMAT_LONG', ' %d日%m月%Y年 ');
向版主檢舉   已記錄
seethrou
訪客
« 回覆文章 #11 於: 十月 28, 2005, 01:47:15 am »



感謝您的努力和不斷跟進!  smiley01_037   smiley01_037


---------------------------------------------------------------------------
另外如果有時間和條件許可的,請研究一下,看看下面的修改,是否可以引進。
它可以使用通用性的日期格式,在日期輸入時比較靈活,相信會對使用中文的朋友特別有幫助,


為方便討論,另開一個主題,請參考
[修改][討論]通用性的日期格式
http://open.38.com/index.php?topic=1545.msg5759#msg5759

向版主檢舉   已記錄
jeanchiu1019
初學者
*
離線 離線

文章: 30


« 回覆文章 #12 於: 十月 29, 2005, 01:25:17 am »

//--- convert and encode begin--------
        $web_charset = constant('CHARSET');
       $email_charset = constant('EMAIL_CHARSET');
       
         if ($web_charset != $email_charset)
      {
            $subject  = iconv($web_charset,$email_charset,$subject);
            $from_name = iconv($web_charset,$email_charset,$from_name);
            $to_name  = iconv($web_charset,$email_charset,$to_name);
      }

      $subject    = $this->encode_str_Q($subject, $email_charset);
      $from_name   = $this->encode_str_Q($from_name,  $email_charset);
      $to_name   = $this->encode_str_Q($to_name, $email_charset);

      //--- convert and encode end-----------


這個code我用不行吔~~其他的都可以~~~
但一加上第七項~~就有錯誤了~~
目前內容是Big5沒錯~~~但是寄件者和標題還是亂碼~~~~

please help me

小妹jean
向版主檢舉   已記錄
Owl
初學者
*
離線 離線

文章: 46


« 回覆文章 #13 於: 十月 29, 2005, 01:03:07 pm »

//--- convert and encode begin--------
 $web_charset = constant('CHARSET');
 $email_charset = constant('EMAIL_CHARSET');
 
 if ($web_charset != $email_charset)
 {
 $subject = iconv($web_charset,$email_charset,$subject);
 $from_name = iconv($web_charset,$email_charset,$from_name);
 $to_name = iconv($web_charset,$email_charset,$to_name);
 }

 $subject = $this->encode_str_Q($subject, $email_charset);
 $from_name = $this->encode_str_Q($from_name, $email_charset);
 $to_name = $this->encode_str_Q($to_name, $email_charset);

 //--- convert and encode end-----------


這個code我用不行吔~~其他的都可以~~~
但一加上第七項~~就有錯誤了~~
目前內容是Big5沒錯~~~但是寄件者和標題還是亂碼~~~~

please help me

小妹jean
第七項就是針對寄件者和標題亂碼而做的。

加了後,是怎麼樣的錯誤?( error message ?)
您的 encode_str_Q 是加在哪裏?(必須在 function send 的外面, class email 裡面)
chinese_tc_utf-8.php 裏有加 'EMIAL_CHARSET' 嗎?

向版主檢舉   已記錄
jeanchiu1019
初學者
*
離線 離線

文章: 30


« 回覆文章 #14 於: 十月 31, 2005, 12:33:28 am »

//--- add header encode -- start
   function encode_str_Q($str, $email_charset)
   {
      if ( $str == '') return $str;
        $encoded = preg_replace("[\r\n]", "", $str);
        $encoded = preg_replace('/([\000-\011\013\014\016-\037\075\077\137\177-\377])/e',
                  "'='.sprintf('%02X', ord('\\1'))", $encoded);
        $encoded = str_replace(" ", "_", $encoded);
        $encoded = preg_replace('/^(.*)$/m', " =?". $email_charset."?Q?\\1?=", $encoded);
        return $encoded;
   }
 // --- add header encode -- end */

    function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = '')
       {//--- convert and encode begin--------
        $web_charset = constant('CHARSET');
       $email_charset = constant('EMAIL_CHARSET');
       
         if ($web_charset != $email_charset)
      {
            $subject  = iconv($web_charset,$email_charset,$subject);
            $from_name = iconv($web_charset,$email_charset,$from_name);
            $to_name  = iconv($web_charset,$email_charset,$to_name);
      }

      $subject    = $this->encode_str_Q($subject, $email_charset);
      $from_name   = $this->encode_str_Q($from_name,  $email_charset);
      $to_name   = $this->encode_str_Q($to_name, $email_charset);

      //--- convert and encode end-----------



我是這樣加進去地~~~

但還是有問題~~~

error message是

Fatal error: Cannot redeclare encode_str_q() /includes/classes/email.php on line 509






------------------------------------------------------

然後我重頭再做一次~~一步一步的加~~每加一行就試send 一次~~
加到這裡時

 function add_text($text = '')
    {
       //---- email in different charset begin -----
        $web_charset = constant('CHARSET');
       $email_charset = constant('EMAIL_CHARSET');

      if ($web_charset != $email_charset)
      {
         $text  = iconv($web_charset,$email_charset,$text);
      }
        //----- email in different charset end -----

      $this->text = zen_convert_linefeeds(array("\r\n", "\n", "\r"), $this->lf, $text);
    }

就出現error說Fatal error: Call to undefined function: iconv() in /includes/classes/email.php on line 167


167是 $text  = iconv($web_charset,$email_charset,$text);


我己經連續很多天一直重覆1-7的步驟了~~~但至今都尚未成功~~~
 smiley01_024 smiley01_036 smiley01_052 smiley01_040 smiley01_029 smiley01_028 smiley01_026 smiley01_022
哪位高手可以幫幫偶吶~~~鳴~~~~~
« 最後編輯時間: 十一月 01, 2005, 09:54:27 am 由 jeanchiu1019 » 向版主檢舉   已記錄
頁: [1] 2   向上
  寄送主題  |  列印  
 
前往:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006, Simple Machines LLC Valid XHTML 1.0! Valid CSS!