作者 主題: mail 亂碼的問題...  (閱讀 16613 次)

0 會員 與 1 訪客 正在閱讀本文。

湯包

  • 榮譽博士
  • 鑽研的研究生
  • *****
  • 文章數: 923
  • 性別: 男
    • 檢視個人資料
    • 湯包的部落格
mail 亂碼的問題...
« 於: 2013-01-27 04:13 »
小弟初學 PHP 遇到疑難,還請諸位學長指點一二 :-[

小弟在 linux 系統下寫了一個 php 程式,就只是簡單的 form to mail ,同樣的內容,寄到不同的信箱
包括:
   GMail
   Hotmail
   易達網
   Synology NAS 的 Mail Server
   Exchange 2003
   
   寄到 GMail ,使用 GMail Web Mail 去看信件內容,全部資訊的正常
                            使用 Android 手機內建的 GMail Apps 去看,也都正常
   寄到 Hotmail,使用 Hotmail Web Mail 去看信也正常
                               使用 Windows Live Mail 去看信也正常
                               使用 Android Hotmail Apps 去看信也正常
   寄到易達網,使用易達網Web Mail 去看信也正常
                           使用Android 手機內建的"電子郵件" Apps 去看信也正常
   寄到Synology NAS,使用Roundcube Web Mail 去看信也正常
                                          使用Android 手機內建的"電子郵件" Apps 去看信也正常
   寄到 Exchange 2003,使用 MS Outlook 去看信也正常
                                             使用OWA 去看信也正常
                                             使用Android 手機內建的"電子郵件" Apps 去看信卻都是亂碼!

        小弟無法理解的是,同樣一封信,寄到易達網、寄到 Synology NAS ,用 Android 手機的同樣一個 Apps "電子郵件" 收信,都是正常
        寄到 Exchange 2003 ,用 Android 手機的同樣一個 Apps "電子郵件" 收信,卻是亂碼,

        而且這封信是保存在 Exchange Server 上的(不是收到個人資料夾)
        用 MS Outlook 2003、OWA 去看信,內容都是正常的...

        請教一下,要怎麼樣才能讓寄到 Exchange 2003 的信,用 Android 電子郵件 Apps 收件是正常的?
        這個問題也讓我很困擾,因為我們老董,經常用 HTC 手機,收到朋友從 HiNet WebMail 寄到公司的 Exhcnage 2003 的信,都是亂碼....


代碼: [選擇]
<?php

define
'LNCR'linebreak() );

function 
linebreak(){
    
$os strtolower(PHP_OS);
    switch( 
true ){
        case (
"\\" == DIRECTORY_SEPARATOR) : // windows
            
return "\x0d\x0a" 
        case ( 
strpos($os'darwin') !== false ) : // Mac
            
return "\x0d" ;
        default : 
            return 
"\x0a" // *nix
    
};
}

$mail_from 'nobody@company.com.tw';
$email_subject '=?UTF-8?B?' base64_encode('線上報名') . '?=';
$email_to '=?UTF-8?B?' base64_encode('大哥') . '?=<bigbrother@company.com.tw>';
$email_cc '=?UTF-8?B?' base64_encode('小妹') . '?=<sister@gmail.com>,' LNCR;
$email_cc  .= ' =?UTF-8?B?' base64_encode('老三') . '?=<third@yahoo.com.tw>,' .  LNCR;
$email_cc  .= ' =?UTF-8?B?' base64_encode('老三') . '?=<third@synologynas.com.tw>,' LNCR;
$email_cc  .= ' =?UTF-8?B?' base64_encode('老四') . '?=<jumior@synologynas.com.tw>';
$email_bcc '=?UTF-8?B?' base64_encode('湯包') . '?=<tombo@hotmail.com>,' .  LNCR;
$email_bcc .= ' =?UTF-8?B?' base64_encode('湯包') . '?=<tombo@gmail.com>,' LNCR;
$email_bcc .= ' =?UTF-8?B?' base64_encode('湯包') . '?=<tombo@url.com.tw>,' LNCR;
$email_bcc .= ' =?UTF-8?B?' base64_encode('湯包') . '?=<tombo@exchange.com.tw>,' LNCR;
$email_bcc .= ' =?UTF-8?B?' base64_encode('湯包') . '?=<tombo@synologynas.com.tw>';
     
function 
died($error) {
        
// your error code can go here
        
echo "很抱歉您填寫的資料錯誤";
        echo 
"錯誤訊息如下.<br /><br />";
        echo 
$error."<br /><br />";
        echo 
"請<a href='mailform.php'>回到上一頁</a>重新輸入<br /><br />";
        die();
    }
     
    
// validation expected data exists
    
if(!isset($_POST['name']) ||
        !isset(
$_POST['gender']) ||
        !isset(
$_POST['ageRad']) ||
        !isset(
$_POST['mobile']) ||
!isset($_POST['agreeRad']) ||
        
died('請您確實填寫所有欄位,謝謝!');       
    }
    
    
$name $_POST['name']; // required
    
$gender $_POST['gender']; // required
    
$ageRad $_POST['ageRad']; // not required
    
$email_from $_POST['email']; // required
    
$mobile $_POST['mobile']; // not required
    
$agreeRad $_POST['agreeRad']; // required
     
    
$error_message '';
    
$email_exp '/^[A-Za-z0-9._%-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}$/';
if(!preg_match($email_exp,$email_from)) {
$error_message .= '電子郵件地址格式錯誤,請再確認一次.<br />';
}
if(strlen($error_message) > 0) {
died($error_message);
}

function 
clean_string($string) {
      
$bad = array("content-type","bcc:","to:","cc:","href""select""insert");
      return 
str_replace($bad,"",$string);
    }
    
    
$boundary uniqid('np');
    
    
// create email headers
$headers  'MIME-Version: 1.0' LNCR;

// $headers .= 'Content-type: text/html; charset=UTF-8' . LNCR;
$headers .= "Content-Type: multipart/alternative;boundary=" $boundary LNCR

$headers .= 'From: ' $mail_from LNCR;
$headers .= 'To: ' $email_to LNCR;
$headers .= 'Cc: ' $email_cc LNCR;
$headers .= 'Bcc: ' $email_bcc LNCR;
$headers .= 'Reply-To: ' $mail_from LNCR;

// create email body
// 
$email_message 'This is a MIME encoded message.';
$email_message .= LNCR LNCR '--' $boundary LNCR;
$email_message .= 'Content-type: text/plain;charset=utf-8' LNCR LNCR;
 
$email_message .= 'This is the text/plain version.';
 
$email_message .= '線上報名資訊:' LNCR LNCR;
 
$email_message .= '姓名:' clean_string($name) . LNCR;
 
$email_message .= '性別:' clean_string($gender) . LNCR;
$email_message .= '年齡:' clean_string($ageRad) . LNCR;
$email_message .= '電子信箱:' clean_string($email_from) . LNCR;
$email_message .= '手機:' clean_string($mobile) . LNCR;
$email_message .= '是否同意:' clean_string($agreeRad) . LNCR;
 
$email_message .= LNCR LNCR '--' $boundary LNCR;
 
$email_message .= 'Content-type: text/html;charset=utf-8' LNCR LNCR;
 
$email_message .= '<b>線上報名資訊</b>:<br /><br />';
$email_message .= '姓名:<font color="blue">' clean_string($name) . '</font><br />';
$email_message .= '性別:<font color="blue">' clean_string($gender) . '</font><br />';
$email_message .= '年齡:<font color="blue">' clean_string($ageRad) . '</font><br />';
$email_message .= '電子信箱:<font color="blue">' clean_string($email_from) . '</font><br />';
$email_message .= '手機:<font color="blue">' clean_string($mobile) . '</font><br />';
$email_message .= '是否同意:<font color="blue">' clean_string($agreeRad) . '</font><br />';
$email_message .= LNCR LNCR '--' $boundary '--';

@mail($email_to$email_subject$email_message$headers);  
?>

 
<!-- include your own success html here -->
<link href="css/t_layout.css" rel="stylesheet" type="text/css" />
<link href="css/t_menu.css" rel="stylesheet" type="text/css" />
<link href="css/slideshow.css" rel="stylesheet" type="text/css" />
<script type=text/javascript src="js/jquery.1.6.4.js"></script>
<script type=text/javascript src="js/jquery.slideshow.lite.js"></script>
<script type=text/javascript src="js/jquery-latest.min.js"></script>
<script src="kent.js"></script>
<script type="text/javascript">
$(function(){
// 幫 #menu li 加上 hover 事件
$('#menu>li').hover(function(){
// 先找到 li 中的子選單
var _this = $(this),
_subnav = _this.children('ul');

// 變更目前母選項的背景顏色
// 同時顯示子選單(如果有的話)
_this.css('backgroundColor', '#0084c4').siblings().css('backgroundColor', '');
_subnav.css('display', 'block');
} , function(){
// 同時隱藏子選單(如果有的話)
// 也可以把整句拆成上面的寫法
$(this).children('ul').css('display', 'none');
});

// 取消超連結的虛線框
$('a').focus(function(){
this.blur();
});
});
</script>
<style type="text/css">
<!--
.style1 {color: #990000}
-->
</style>

<div id="wrapper" align="center">
<div id="head">
<?php include("_header.php");?>
</div>

<div id="main_menu">
<div id="main_nav">
<?php include("_menu.php");?>
<div class="a"></div>
</div>
</div>

<div id="content">
<div align="center">
<div id="text">
<div id="text_pic1"><img src="images/tyy.jpg" /></div>
<div id="text_success" align="left">
<!-- 成功傳輸表單的訊息 -->

成功 !!<br /><br />
您已完成線上報名。
</div>
<!-- 頁腳 -->

</div>
</div>
</div>

<div id="footer" align="left">
<div class="footer_block">
<?php include("_foot.php");?>
<div class="footer_logo"><a href="http://www.company.com.tw/" target="_blank"><img src="images/logo.png" border="0" /></a></div>
<div class="footer_fb"><a href="http://www.facebook.com" target="_blank"><img src="images/fb.png" border="0" /></a></div>
<div class="footer_info2">版權所有 禁止轉載 © 2012, Company All Rights Reserved.</div>
</div>
</div>
</div>

人必先置於死地而後生
科技來自人性
想像是科技之母

twu2

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 5416
  • 性別: 男
    • 檢視個人資料
    • http://blog.teatime.com.tw/1
Re: mail 亂碼的問題...
« 回覆 #1 於: 2013-01-27 09:19 »
自己比對一下 email source 吧. (如果用的那個 client 有這功能的話)

micmic3

  • 俺是博士!
  • *****
  • 文章數: 1693
    • 檢視個人資料

湯包

  • 榮譽博士
  • 鑽研的研究生
  • *****
  • 文章數: 923
  • 性別: 男
    • 檢視個人資料
    • 湯包的部落格
Re: mail 亂碼的問題...
« 回覆 #3 於: 2013-01-29 16:36 »
手機上的應用程式沒辦法看到 Source...

我一開始只是很簡單的輸出 HTML 內容,在"電子郵件" via Exchange 上還能正常看到
但是在 Synolog NAS 上的 Mail Server 收到時,
會被 Spamassassin 當成廣告信,因為內容不是標準格式

所以後來改成 Multipart 格式,它有純文字及HTML兩部份,我的文字都是設定 utf-8
不確定是不是這個問題...我先試看看.... :(
人必先置於死地而後生
科技來自人性
想像是科技之母

twu2

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 5416
  • 性別: 男
    • 檢視個人資料
    • http://blog.teatime.com.tw/1
Re: mail 亂碼的問題...
« 回覆 #4 於: 2013-01-29 17:22 »
不需要在手機上看 source 吧.
理論上, 信被 server 收下後, 應該不管用什麼 client 來收走都應該不會變.

hikohan

  • 俺是博士!
  • *****
  • 文章數: 1288
    • 檢視個人資料
Re: mail 亂碼的問題...
« 回覆 #5 於: 2013-01-29 17:29 »
手機用openwebmail看還好,語系直接在web上轉。

gMail的語系也OK....  ;D
lifeIsFunWithPHP.

湯包

  • 榮譽博士
  • 鑽研的研究生
  • *****
  • 文章數: 923
  • 性別: 男
    • 檢視個人資料
    • 湯包的部落格
Re: mail 亂碼的問題...
« 回覆 #6 於: 2013-02-02 21:04 »
不需要在手機上看 source 吧.
理論上, 信被 server 收下後, 應該不管用什麼 client 來收走都應該不會變.

理論上是這樣沒錯....
不過我在 OWA & Microsoft Outlook 2003 上看到的 Mail 都是正常的中文字
可是在"電子郵件" Apps 看到的就是如圖的亂碼....

所以,應該是有什麼地方是錯了,讓 "電子郵件" 解讀成亂碼...
因為我公司董仔反應他某個朋友也是經常從 Hinet webmail 轉寄郵件給他,他用 htc 手機內建的"電子郵件"收也都是亂碼,但是從"向外看"卻都是正常的中文字
« 上次編輯: 2013-02-02 21:07 由 湯包 »
人必先置於死地而後生
科技來自人性
想像是科技之母

hikohan

  • 俺是博士!
  • *****
  • 文章數: 1288
    • 檢視個人資料
Re: mail 亂碼的問題...
« 回覆 #7 於: 2013-02-02 21:20 »
今天試了winDroid跟aquaMail,最後我還是相信OWM。
lifeIsFunWithPHP.

twu2

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 5416
  • 性別: 男
    • 檢視個人資料
    • http://blog.teatime.com.tw/1
Re: mail 亂碼的問題...
« 回覆 #8 於: 2013-02-03 08:06 »
不需要在手機上看 source 吧.
理論上, 信被 server 收下後, 應該不管用什麼 client 來收走都應該不會變.

理論上是這樣沒錯....
不過我在 OWA & Microsoft Outlook 2003 上看到的 Mail 都是正常的中文字
可是在"電子郵件" Apps 看到的就是如圖的亂碼....

所以,應該是有什麼地方是錯了,讓 "電子郵件" 解讀成亂碼...
因為我公司董仔反應他某個朋友也是經常從 Hinet webmail 轉寄郵件給他,他用 htc 手機內建的"電子郵件"收也都是亂碼,但是從"向外看"卻都是正常的中文字
同一份 source, 不同 email client 解讀不同, 為什麼會單純認定 source 沒錯?
這個當然很大的可能是 client 的 bug, 不過, 也有可能是 email source 本身的問題, 只是某些 client 會特別處理掉.

我的經驗告訴我, 信寄到一般 unix like 的 server, 只會加上 header.
但是寄到 exchange 上頭, 信件的內容編碼會方式可能會變.

湯包

  • 榮譽博士
  • 鑽研的研究生
  • *****
  • 文章數: 923
  • 性別: 男
    • 檢視個人資料
    • 湯包的部落格
Re: mail 亂碼的問題...
« 回覆 #9 於: 2013-02-04 17:10 »
不需要在手機上看 source 吧.
理論上, 信被 server 收下後, 應該不管用什麼 client 來收走都應該不會變.

理論上是這樣沒錯....
不過我在 OWA & Microsoft Outlook 2003 上看到的 Mail 都是正常的中文字
可是在"電子郵件" Apps 看到的就是如圖的亂碼....

所以,應該是有什麼地方是錯了,讓 "電子郵件" 解讀成亂碼...
因為我公司董仔反應他某個朋友也是經常從 Hinet webmail 轉寄郵件給他,他用 htc 手機內建的"電子郵件"收也都是亂碼,但是從"向外看"卻都是正常的中文字
同一份 source, 不同 email client 解讀不同, 為什麼會單純認定 source 沒錯?
這個當然很大的可能是 client 的 bug, 不過, 也有可能是 email source 本身的問題, 只是某些 client 會特別處理掉.

我的經驗告訴我, 信寄到一般 unix like 的 server, 只會加上 header.
但是寄到 exchange 上頭, 信件的內容編碼會方式可能會變.

因為我們平常用其他發信軟體,如 outlook express, MS Outlook 等等,都在 "電子郵件" Apps 裡看都是正常的...
另外,我查到問題的原因了,程式已修正了... 現在所有收信軟體看都是正常的了 ;D
只能說 "電子郵件" Apps 沒有做太多容錯的處理,所以信件內容必須完全依照標準來做,要不然就是會有亂碼....
« 上次編輯: 2013-02-04 17:24 由 湯包 »
人必先置於死地而後生
科技來自人性
想像是科技之母

湯包

  • 榮譽博士
  • 鑽研的研究生
  • *****
  • 文章數: 923
  • 性別: 男
    • 檢視個人資料
    • 湯包的部落格
Re: mail 亂碼的問題...
« 回覆 #10 於: 2013-02-04 17:22 »
Subject亂碼的部份,必須將Subject文字內容編碼
例如:
代碼: [選擇]
subject = '=?UTF-8?B?' . base64_encode('郵件主旨字串') . '?=';
信箱人名亂碼的部份,也是要編碼
例如:
代碼: [選擇]
$email_to = '=?UTF-8?B?' . base64_encode('老大') . '?=<first@company.com.tw>,' . LNCR;
$email_to .= ' =?UTF-8?B?' . base64_encode('老二') . '?=<second@company.com.tw>';

先產生一個唯一的序號,在 Mail Header 及 Mail Body 都會用到
代碼: [選擇]
//產生一個唯一的序號
// $boundary = md5(time()); 用這個也行
$boundary = uniqid('np');

至於 CC 與 BCC 信箱地址,必須寫在 Header 裡,如果有中文名字一樣要做編碼
代碼: [選擇]
// create email headers
$headers  = 'MIME-Version: 1.0' . LNCR;

// $headers .= 'Content-type: text/html; charset=UTF-8' . LNCR;
$headers .= "Content-Type: multipart/alternative;boundary=" . $boundary . LNCR;

$headers .= 'From: ' . $mail_from . LNCR;
$headers .= 'To: ' . $email_to . LNCR;
$headers .= 'Cc: ' . $email_cc . LNCR;
$headers .= 'Bcc: ' . $email_bcc . LNCR;
$headers .= 'Reply-To: ' . $mail_from . LNCR;

接下來就是 E-Mail Body
$email_message = 'This is a MIME encoded message.';
$email_message .= LNCR . LNCR . '--' . $boundary . LNCR;
$email_message .= 'Content-Transfer-Encoding: 8bit' . LNCR;
$email_message .= 'Content-type: text/plain;charset=utf-8' . LNCR . LNCR;

$email_message .= '純文字內容' . LNCR . LNCR;
$email_message .= LNCR . LNCR . '--' . $boundary . LNCR;
$email_message .= 'Content-Transfer-Encoding: base64' . LNCR;
$email_message .= 'Content-type: text/html;charset=utf-8' . LNCR . LNCR;

$email_message .= base64_encode('HTML格式郵件內容');
$email_message .= LNCR . LNCR . '--' . $boundary . '--';

最後把上面處理好的字串傳入即可。
代碼: [選擇]
@mail($email_to, $email_subject, $email_message, $headers);
我少的就是把 HTML 格式的郵件內容做編碼,至於要做 base64 或是 quoted-printable 都行,只是要記得去修改對應的邊碼方式
« 上次編輯: 2013-02-04 17:33 由 湯包 »
人必先置於死地而後生
科技來自人性
想像是科技之母

micmic3

  • 俺是博士!
  • *****
  • 文章數: 1693
    • 檢視個人資料
Re: mail 亂碼的問題...
« 回覆 #11 於: 2013-02-04 18:54 »
如果只是 Subject 亂碼的確用 base64_encode 就好了