少用但始终都会碰到 - 发邮件

  • 作者:KK

  • 发表日期:2017.4.24


不建议用自带的mail函数

如果使用mail函数发邮件,需要本地搭建SMTP服务器,试过你才知道麻烦


自定义发个发邮件的函数

咱通常都追求轻量级解决方案,而且也不必自己搭SMTP服务器,在外面找一个就是了,比如QQ邮箱啊,设置开放一下SMTP功能就是

/**
 * 发送邮件,适用于无SSL协议要求的
 * @param string $targetAddr 收信邮箱
 * @param string $subject 邮件标题
 * @param string $body 邮件内容
 * @param string $cc 抄送邮箱
 * @param string $bcc 密送邮箱
 * @return array 发送结果,里面的success=是否成功,message在失败时会是非空字符串
 * @author KK
 */
function sendEmail($targetAddr, $subject, $body = '', $cc = '', $bcc = ''){
	/* 自己找个SMTP账号来配置一下 */
	$smtpUsername = 'xxxx@yyy.com'; //smtp账号
	$smtpPassword = 'passwdaaaa'; //SMTP账号的密码
	$smtpHost = 'smtp.qq.com'; //SMTP服务器,比如直接用QQ邮箱
	$smtpPort = 25; //SMTP服务器端口
	$smtpTimeOut = 20;
	
	$errorInfo = '';
	$eol = "\r\n";
	$headers = 'Content-Type: text/html; charset="utf-8"' . $eol . 'Content-Transfer-Encoding: base64';
	$aHeaders = explode($eol,$headers);
	if($body){
		$bodyContent = preg_replace("/^\./", '..', explode($eol, $body));
	}

	$aSmtp = array(
		array(
			'EHLO DIYDIYDIY' 				. $eol, '220,250',
			"HELO error: ",
		),
		array(
			'AUTH LOGIN' 					. $eol, '334',
			"AUTH error:",
		),
		array(
			base64_encode($smtpUsername) 	. $eol, '334',
			"AUTHENTIFICATION error : ",
		),
		array(
			base64_encode($smtpPassword)	. $eol, '235',
			"AUTHENTIFICATION error : ",
		),
		array(
			'MAIL FROM: <' . $smtpUsername . '>'	. $eol,	'250',
			"MAIL FROM error: ",
		),
	);

	$aSendTargets = explode(',', $targetAddr);

	if($cc){
		$ccArray = explode(',', $cc);
		for($i = 0; $i < count($ccArray); $i++){
			$aSendTargets[] = $ccArray[$i];
		}
	}

	if($bcc){
		$bccArray = explode(',', $bcc);
		for($i = 0; $i < count($bccArray); $i++){
			$aSendTargets[] = $bccArray[$i];
		}
	}

	$sendTargetCount = count($aSendTargets);
	for($i = 0; $i < $sendTargetCount; $i++){
		$target = trim($aSendTargets[$i]);
		if($target){
			$aSmtp[] = array(
				'RCPT TO: <' . $target . '>' . $eol, '250',
				'RCPT TO error: '
			);
		}
	}

	$aSmtp[] = array('DATA' . $eol, '354', 'DATA error: ');
	$aSmtp[] = array('From: ' . $smtpUsername . $eol, '', '');
	$aSmtp[] = array('To: '. $targetAddr . $eol , '', '');
	if($cc){
		$aSmtp[] = array('Cc: ' . $cc . $eol, '', '');
	}
	if($bcc){
		$aSmtp[] = array('Bcc: ' . $bcc . $eol, '', '');
	}

	$aSmtp[] = array('Subject: ' . $subject . $eol, '', '');

	foreach($aHeaders as $header){
		$aSmtp[] = array($header . $eol, '', '');
	}

	$aSmtp[] = array($eol, '', '');

	if($bodyContent){
		foreach($bodyContent as $b){
			$aSmtp[] = array(base64_encode($b . $eol) . $eol, '', '');
		}
	}

	$aSmtp[] = array('.' . $eol, '250', 'DATA(end)error: ');
	$aSmtp[] = array('QUIT'. $eol, '221', 'QUIT error: ');

	$fsockHandle = fsockopen($smtpHost, $smtpPort, $errno, $errstr, $smtpTimeOut);
	if($fsockHandle){
		while($result = fgets($fsockHandle, 1024)){
			if(substr($result, 3, 1) == ' '){
				break;
			}
		}

		foreach($aSmtp as $command){
			fputs($fsockHandle, $command[0]);
			if($command[1]){

				while($result = fgets($fsockHandle, 1024)){
					if(substr($result, 3, 1) == ' '){
						break;
					}
				}

				if(!strstr($command[1],substr($result, 0, 3))){
					//The codes below will recorde the detail process, when the response code is not an expected code, please don't delete them.
					//$errorInfo .= $command[2] . $result . $eol;
				}
			}
		}

		fclose($fsockHandle);
		
	}else{
		$errorInfo .= 'Send Mail Error: Cannot conect to Smtp host: ' . $smtpHost . $eol . $errno . $eol . $errstr . $eol;
	}

	if($errorInfo){
		$errorInfo .= 'Mail Data>>>>TO: ' . $to . $eol;
		$errorInfo .= 'Mail Data>>>>CC: ' . $cc . $eol;
		$errorInfo .= 'Mail Data>>>>BCC: ' . $bcc . $eol;
		$errorInfo .= 'Mail Data>>>>SUBJECT: ' . $subject . $eol;
		$errorInfo .= 'Mail Data>>>>BODY: ' . $body . $eol;
		$return = array('error' => $errorInfo);
		return array(
			'success' => false,
			'message' => $errorInfo
		);
	}else{
		return array(
			'success' => true,
			'message' => 'OK'
		);
	}
}

sendEmail('收信邮箱', '邮件标题', '邮件内容');
sendEmail('123456@qq.com', '测试邮件', '邮件内容………………');

这是我多年来积累的一个发邮件函数,你可以改装一下嵌入到你的实际项目框架中使用