PHP Conference Japan 2024

郵件函式

目錄

新增註解

使用者貢獻的註解 6 則註解

webmaster at weethet dot nl
17 年前
如先前所述,對於 Windows 使用者來說,有一個假的 sendmail 選項。更詳細的描述說明如何執行此操作

如果您在使用 Windows 和某種 WAMP 組合(XXAMP、WAMP Server 等)的測試伺服器,您會注意到 PHP sendmail 命令(mail())無法運作。Windows 根本沒有提供 sendmail 語句 ...

不過,有一個簡單的技巧可以讓它運作;

1) 從 http://glob.com.au/sendmail/ 下載(或使用附加的檔案)sendmail.zip

2) 將其解壓縮到您 C: 磁碟機上的資料夾中(最好使用簡單的路徑,例如 c:\wamp\sendmail -- 長檔名可能會導致問題)

3) 編輯您的 PHP.INI 檔案(注意:WAMP 使用者應該從 WAMP 選單存取他們的 php.ini 檔案)。前往 [mail function] 區段並進行如下修改

[mail function]
; 僅限 Win32。
;SMTP =

; 僅限 Win32。
;sendmail_from =

; 僅限 Unix。您也可以提供引數(預設值:"sendmail -t -i")。
sendmail_path = "C:\wamp\sendmail\sendmail.exe -t"

; 強制將指定參數新增為額外參數
; 傳遞到 sendmail 二進制檔案。這些參數將始終替換
; mail() 的第五個參數值,即使在安全模式下也是如此。
;mail.force_extra_paramaters =

.. 並儲存變更。

4) 開啟 sendmail.ini 並將設定修改為

[sendmail]

; 您必須將 mail.mydomain.com 變更為您的 smtp 伺服器,
; 或 IIS 的「pickup」目錄。(通常是 C:\Inetpub\mailroot\Pickup)
; 透過 IIS 的 pickup 目錄傳送的電子郵件會導致 sendmail
; 執行速度更快,但您不會將錯誤訊息傳回呼叫的
; 應用程式。

smtp_server=mail.yourdomain.com

; smtp 連接埠(通常為 25)

smtp_port=25

; 此伺服器的預設網域將從登錄檔中讀取
; 當未提供電子郵件地址時,這將附加到電子郵件地址
; 如果您想要覆寫登錄檔中的值,請取消註解並修改

default_domain=yourdomain.com

; 將 smtp 錯誤記錄到 error.log(預設為與 sendmail.exe 相同的目錄)
; 取消註解以啟用記錄
; error_logfile=sendmail_error.log

; 建立 debug.log 作為偵錯記錄(預設為與 sendmail.exe 相同的目錄)
; 取消註解以啟用偵錯
; debug_logfile=sendmail_debug.log

; 如果您的 smtp 伺服器需要驗證,請修改以下兩行

;auth_username=
;auth_password=

; 如果您的 smtp 伺服器在使用 smtp 驗證前使用 pop3,請修改
; 以下三行

pop3_server=mail.yourdomain.com
pop3_username=you@yourdomain.com
pop3_password=mysecretpassword

; 若要強制傳送者始終為以下電子郵件地址,請取消註解並
; 使用有效的電子郵件地址填寫。這只會影響「MAIL FROM」
; 命令,它不會修改郵件內容的「From:」標頭

force_sender=you@yourdomain.com

; sendmail 將在 ehlo/helo 中使用您的主機名稱和預設網域
; smtp 招呼語。如果需要,您可以手動設定 ehlo/helo 名稱

hostname=

建議在第一次嘗試時使用選用的錯誤和偵錯記錄,這樣如果無法運作,您就會知道哪裡出了問題。
Force_sender 也是選用的,但建議使用,以避免在伺服器端造成混淆。
顯然,mail.yourdomain.com、you@yourdomain.com 和 mysecretpassword 應該是您的 SMTP 伺服器的相關資訊。
現在重新啟動 WAMP 服務(主要是 Apache,以便 PHP 重新讀取其設定)。

現在您可以像 Unix 使用者一樣使用 PHP mail() 語句了 ...
jcwebb at dicoe dot com
18 年前
損毀的附件???
我花了很多時間處理損毀的附件(各種檔案類型) - 答案:在 $msg.=$file \r\n \r\n 之後需要一個空行[令人難以置信但真實]。
這是一些用於傳送附件的實用程式碼,並根據使用者的電子郵件閱讀器顯示 html 或文字。

我使用許多不同的系統,所以...

<?php # 作業系統是 Windows、Mac 還是 Linux
if (strtoupper(substr(PHP_OS,0,3)=='WIN')) {
$eol="\r\n";
} elseif (
strtoupper(substr(PHP_OS,0,3)=='MAC')) {
$eol="\r";
} else {
$eol="\n";
}
?>

<?php
# 附件檔案
$f_name="../../letters/".$letter; // 使用相對路徑,否則會有大麻煩。$letter 是我要附加的檔案。
$handle=fopen($f_name, 'rb');
$f_contents=fread($handle, filesize($f_name));
$f_contents=chunk_split(base64_encode($f_contents)); // 使用 base64_encode() 編碼資料以便傳輸;
$f_type=filetype($f_name);
fclose($handle);
# 收件者電子郵件地址
$emailaddress="user@example.com";
# 郵件主旨
$emailsubject="這是一封帶有 PDF 附件的郵件".date("Y/m/d H:i:s");
# 郵件內文
ob_start();
require(
"emailbody.php"); // 我建立了一個簡單又漂亮的頁面,用於顯示在電子郵件中
$body=ob_get_contents(); ob_end_clean();

# 通用標頭
$headers .= 'From: Jonny <jon@example.com>'.$eol;
$headers .= 'Reply-To: Jonny <jon@example.com>'.$eol;
$headers .= 'Return-Path: Jonny <jon@example.com>'.$eol; // 這兩個設定回覆地址
$headers .= "Message-ID:<".$now." TheSystem@".$_SERVER['SERVER_NAME'].">".$eol;
$headers .= "X-Mailer: PHP v".phpversion().$eol; // 這兩個標頭有助於避免垃圾郵件過濾器
# 分隔標記和多類型標頭的邊界
$mime_boundary=md5(time());
$headers .= 'MIME-Version: 1.0'.$eol;
$headers .= "Content-Type: multipart/related; boundary=\"".$mime_boundary."\"".$eol;
$msg = "";

# 附件
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: application/pdf; name=\"".$letter."\"".$eol; // 有時我需要發送 MS Word 檔案,請使用 'msword' 而非 'pdf'
$msg .= "Content-Transfer-Encoding: base64".$eol;
$msg .= "Content-Disposition: attachment; filename=\"".$letter."\"".$eol.$eol; // !! 這行需要兩個換行符號 !! 重要 !!
$msg .= $f_contents.$eol.$eol;
# 設定純文字或 HTML 格式
$msg .= "Content-Type: multipart/alternative".$eol;

# 純文字版本
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: text/plain; charset=iso-8859-1".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol;
$msg .= "這是一封 MIME 格式的多部分郵件。".$eol;
$msg .= "如果您看到此訊息,請更新您的電子郵件軟體。".$eol;
$msg .= "+ + 來自天才 Jon 的純文字電子郵件 + +".$eol.$eol;

# HTML 版本
$msg .= "--".$mime_boundary.$eol;
$msg .= "Content-Type: text/html; charset=iso-8859-1".$eol;
$msg .= "Content-Transfer-Encoding: 8bit".$eol;
$msg .= $body.$eol.$eol;

# 完成
$msg .= "--".$mime_boundary."--".$eol.$eol; // 為了更好的安全性,請用兩個換行符號結束。請參閱 Injection。

# 發送電子郵件
ini_set(sendmail_from,'from@example.com'); // INI 行是為了強制使用寄件者地址!
mail($emailaddress, $emailsubject, $msg, $headers);
ini_restore(sendmail_from);
?>


希望這對您有幫助。
Jon Webb [馬德里&倫敦]

[編輯者 thiago 註:程式碼已修正來自 o.straesser AT gmx DOT de 的錯誤]
anselm at netuxo dot co dot uk
18 年前
如果您不想或無法為您的伺服器設定 sendmail,一個不錯的替代方案是 esmtp - 它是一個只需最少設定即可作為 sendmail 替代品的 smtp 郵件程式:http://esmtp.sourceforge.net/
aweather88 at gmail dot com
18 年前
我花了好幾個小時在網路上搜尋,試圖找出為什麼每次在我的伺服器 (Win2K3,IIS 6.0,PHP4.4.1) 上使用 mail() 函式時,都會收到「WARNING: mail(): SMTP server response: 501 5.5.4 Invalid Address」的警告。我知道基於其他非 IIS 6.0 設定,SMTP 的一切都設定正確。

結果發現 IIS 6.0 SMTP 服務不喜歡郵件標頭中 "From" 欄位的格式。例如:
<?PHP
//此行無法正確發送郵件訊息
$headers .= "From: \"".$fromname."\" <".$fromaddress.">\n";
?>
然而,這個方法有效:
<?PHP
//此行可以正確發送郵件訊息
$headers .= "From: \"".$fromaddress."\"\n";
?>

修復方法在 Microsoft 文件 ID 291828 ( http://support.microsoft.com/?id=291828 ) 中。即使「錯誤」的解決方法適用於 Exchange 2003 上與 UNIX 伺服器通訊的 IIS 6.0,這也解決了問題。只需跳到最後一節關於 Exchange 2003 的部分,並按照指示使用 IIS 6 Resource Kit 中的 MetaBase Explorer 修改 IIS 6 MetaBase。
lawcd at ntlworld dot com
18 年前
如果您使用 exim 並且它在沒有 -i 選項的情況下無法發送郵件,而且您無法輕易更改此設定,那麼您可能需要查看 imap_mail() 函式,它的運作方式幾乎完全相同,而且不使用 exim。大多數網路主機都提供此函式。如果您使用自己的伺服器,則 php 需要編譯 imap 函式庫等等。

請參閱 https://php.dev.org.tw/manual/en/function.imap-mail.php
josh at sdfahrenheit dot com
20 年前
對於任何附件檔案出現亂碼問題的人,請確保您在 php.ini 中將 magic_quotes_runtime 設定為 Off - 它會為您的附加資料添加奇怪的跳脫字元,並導致附件亂碼。

這曾給我帶來各種麻煩。
To Top