吵吵   2011-08-08  阅读:3,844

那天在帮老师用一个客户留言的页面,客户通过先写表单传送过来留言内容等,然后老师想用邮件发送到它的邮箱中去,以方便及时回复。本来想是个很简单的问题,不想他的空间不支持mail()函数,那就只能用socket发了,用smtp协议来发吧。网上找了很多php的类,发现用不了,不过后来找了半天还是找到了一个。

后来就用126邮箱来代发我博客上的评论回复了,这么做的原因一是本身的mail函数是由服务器上的邮件服务器代发的,如果再天上自己的邮箱,那么收到邮件后就会由于发件人和发件邮箱不一致而成为垃圾邮件。第二就是这个邮件是回复不了的,及时别人回复了,也是服务器收到了,而你看不到。总而言之,用自己的126邮箱来代发还是不错的,除了有点慢之外。
好了,这个是邮件发送的类:

debug = FALSE;
$this->smtp_port = $smtp_port;
$this->relay_host = $relay_host;
$this->time_out = 30; //is used in fsockopen()

#

$this->auth = $auth;//auth
$this->user = $user;
$this->pass = $pass;

#

$this->host_name = "localhost"; //is used in HELO command
$this->log_file = "";
$this->sock = FALSE;
}
/* Main Function */

function sendmail($to, $from, $subject = "", $body = "", $mailtype, $cc = "", $bcc = "", $additional_headers = "")
{
$mail_from = $this->get_address($this->strip_comment($from));
$body = ereg_replace("(^|(\r\n))(\.)", "\1.\3", $body);
$header = "MIME-Version:1.0\r\n";

if($mailtype=="HTML"){
$header .= "Content-Type:text/html\r\n";
}

$header .= "To: ".$to."\r\n";

if ($cc != "") {
$header .= "Cc: ".$cc."\r\n";
}

$header .= "From:吵吵<".$from.">\r\n";
$header .= "Subject: ".$subject."\r\n";
$header .= $additional_headers;
$header .= "Date: ".date("r")."\r\n";
$header .= "X-Mailer:By Redhat (PHP/".phpversion().")\r\n";
$utfheader=iconv("UTF-8","GB2312",$header);
list($msec, $sec) = explode(" ", microtime());

$header .= "Message-ID: <".date("YmdHis", $sec).".".($msec*1000000).".".$mail_from.">\r\n";

$TO = explode(",", $this->strip_comment($to));

if ($cc != "") {
$TO = array_merge($TO, explode(",", $this->strip_comment($cc)));
}

if ($bcc != "") {
$TO = array_merge($TO, explode(",", $this->strip_comment($bcc)));
}

$sent = TRUE;

foreach ($TO as $rcpt_to) {
$rcpt_to = $this->get_address($rcpt_to);

if (!$this->smtp_sockopen($rcpt_to)) {
$this->log_write("Error: Cannot send email to ".$rcpt_to."\n");
$sent = FALSE;
continue;
}

if ($this->smtp_send($this->host_name, $mail_from, $rcpt_to, $utfheader, $body)) {
$this->log_write("E-mail has been sent to <".$rcpt_to.">\n");
} else {
$this->log_write("Error: Cannot send email to <".$rcpt_to.">\n");
$sent = FALSE;
}

fclose($this->sock);

$this->log_write("Disconnected from remote host\n");
}
return $sent;
}
/* Private Functions */
function smtp_send($helo, $from, $to, $header, $body = "")
{
if (!$this->smtp_putcmd("HELO", $helo)) {

return $this->smtp_error("sending HELO command");
}

#auth

if($this->auth){
if (!$this->smtp_putcmd("AUTH LOGIN", base64_encode($this->user))) {
return $this->smtp_error("sending HELO command");
}

if (!$this->smtp_putcmd("", base64_encode($this->pass))) {
return $this->smtp_error("sending HELO command");
}
}

#

if (!$this->smtp_putcmd("MAIL", "FROM:<".$from.">")) {
return $this->smtp_error("sending MAIL FROM command");
}

if (!$this->smtp_putcmd("RCPT", "TO:<".$to.">")) {
return $this->smtp_error("sending RCPT TO command");
}

if (!$this->smtp_putcmd("DATA")) {
return $this->smtp_error("sending DATA command");
}
if (!$this->smtp_message($header, $body)) {
return $this->smtp_error("sending message");
}
if (!$this->smtp_eom()) {
return $this->smtp_error("sending . [EOM]");
}
if (!$this->smtp_putcmd("QUIT")) {
return $this->smtp_error("sending QUIT command");
}
return TRUE;
}

function smtp_sockopen($address)
{
if ($this->relay_host == "") {
return $this->smtp_sockopen_mx($address);
} else {
return $this->smtp_sockopen_relay();
}
}
function smtp_sockopen_relay()
{
$this->log_write("Trying to ".$this->relay_host.":".$this->smtp_port."\n");
$this->sock = @fsockopen($this->relay_host, $this->smtp_port, $errno, $errstr, $this->time_out);
if (!($this->sock && $this->smtp_ok())) {
$this->log_write("Error: Cannot connenct to relay host ".$this->relay_host."\n");
$this->log_write("Error: ".$errstr." (".$errno.")\n");
return FALSE;
}
$this->log_write("Connected to relay host ".$this->relay_host."\n");
return TRUE;
}

function smtp_sockopen_mx($address)
{
$domain = ereg_replace("^.+@([^@]+)$", "\1", $address);
if (!@getmxrr($domain, $MXHOSTS)) {
$this->log_write("Error: Cannot resolve MX \"".$domain."\"\n");
return FALSE;
}
foreach ($MXHOSTS as $host) {
$this->log_write("Trying to ".$host.":".$this->smtp_port."\n");
$this->sock = @fsockopen($host, $this->smtp_port, $errno, $errstr, $this->time_out);
if (!($this->sock && $this->smtp_ok())) {
$this->log_write("Warning: Cannot connect to mx host ".$host."\n");
$this->log_write("Error: ".$errstr." (".$errno.")\n");
continue;
}
$this->log_write("Connected to mx host ".$host."\n");
return TRUE;
}
$this->log_write("Error: Cannot connect to any mx hosts (".implode(", ", $MXHOSTS).")\n");
return FALSE;
}

function smtp_message($header, $body)
{
fputs($this->sock, $header."\r\n".$body);
$this->smtp_debug("> ".str_replace("\r\n", "\n"."> ", $header."\n> ".$body."\n> "));
return TRUE;
}

function smtp_eom()
{
fputs($this->sock, "\r\n.\r\n");
$this->smtp_debug(". [EOM]\n");
return $this->smtp_ok();
}

function smtp_ok()
{
$response = str_replace("\r\n", "", fgets($this->sock, 512));
$this->smtp_debug($response."\n");
if (!ereg("^[23]", $response)) {
fputs($this->sock, "QUIT\r\n");
fgets($this->sock, 512);
$this->log_write("Error: Remote host returned \"".$response."\"\n");
return FALSE;
}
return TRUE;
}

function smtp_putcmd($cmd, $arg = "")
{
if ($arg != "") {
if($cmd=="") $cmd = $arg;
else $cmd = $cmd." ".$arg;
}
fputs($this->sock, $cmd."\r\n");
$this->smtp_debug("> ".$cmd."\n");
return $this->smtp_ok();
}

function smtp_error($string)
{
$this->log_write("Error: Error occurred while ".$string.".\n");
return FALSE;
}

function log_write($message)
{
$this->smtp_debug($message);
if ($this->log_file == "") {
return TRUE;
}
$message = date("M d H:i:s ").get_current_user()."[".getmypid()."]: ".$message;
if (!@file_exists($this->log_file) || !($fp = @fopen($this->log_file, "a"))) {
$this->smtp_debug("Warning: Cannot open log file \"".$this->log_file."\"\n");
return FALSE;;
}
flock($fp, LOCK_EX);
fputs($fp, $message);
fclose($fp);
return TRUE;
}

function strip_comment($address)
{
$comment = "\([^()]*\)";
while (ereg($comment, $address)) {
$address = ereg_replace($comment, "", $address);
}
return $address;
}

function get_address($address)
{
$address = ereg_replace("([ \t\r\n])+", "", $address);
$address = ereg_replace("^.*<(.+)>.*$", "\1", $address);
return $address;
}
function smtp_debug($message)
{
if ($this->debug) {
echo $message;
}
}
}
?>


接下来的就是一个例子了,就是我们的博客评论回复邮件通知的代码,可以做个参考。

comment_author_email);
$parent_id = $comment->comment_parent ? $comment->comment_parent : '';
$to = $parent_id ? trim(get_comment($parent_id)->comment_author_email) : '';
$spam_confirmed = $comment->comment_approved;
if (($parent_id != '') && ($spam_confirmed != 'spam') && ($to != $admin_email) && ($comment_author_email == $admin_email)) {
/* 上面的判斷式,決定發出郵件的必要條件:
($parent_id != '') && ($spam_confirmed != 'spam'): 回覆的, 而且不是 spam 才可發, 必需!!
($to != $admin_email) : 不發給 admin.
($comment_author_email == $admin_email) : 只有 admin 的回覆才可發.
可視個人需求修改以上條件.
*/
$wp_email = 'no-reply@' . preg_replace('#^www\.#', '', strtolower($_SERVER['SERVER_NAME'])); // e-mail 發出點, no-reply 可改為可用的 e-mail.
$subject = '吵吵回复了您在【吵吵博客】的留言';
$message = '

  • ' . trim(get_comment($parent_id)->comment_author) . ',您好!您曾在《' . get_the_title($comment->comment_post_ID) . '》的留言吵吵已经回复了。
  • ';
    $message.='

  • '. trim(get_comment($parent_id)->comment_author) .':' . trim(get_comment($parent_id)->comment_content) . '
  • ' . trim($comment->comment_author) . '说:' . trim($comment->comment_content) . '
  • 您可以点击查看' . get_comment_link($parent_id). '
  • ';
    $message.='

  • 欢迎再度光临 ' . get_option('blogname') . '
  • (此邮件由吵吵的邮箱进行代发,如果您有什么想对吵吵说的,可直接回复!)
  • ';
    //$from = "From: \"".get_option('blogname')."\" <$wp_email>";
    //$mail_headers = "$from\nContent-Type: text/html; charset=" . get_option('blog_charset') . "\n";
    //@wp_mail( $to, $subject, $message,$mail_headers);
    include("sendmail.php");//发送邮件类

    $smtpserver = "smtp.126.com";//SMTP服务器
    $smtpserverport = 25;//SMTP服务器端口
    $smtpusermail = "admin@126.com";
    $smtpuser = "admin";//SMTP服务器的用户帐号
    $smtppass = "admin";//SMTP服务器的用户密码

    $smtpemailto = $to;//发送给谁
    $mailsubject = $subject;//邮件主题
    $mailtime = date("Y-m-d H:i:s");
    $mailbody = $message;//邮件内容

    $utfmailbody = iconv("UTF-8","GB2312",$mailbody);//转换邮件编码
    $mailtype = "HTML";//邮件格式(HTML/TXT),TXT为文本邮件

    $smtp = new smtp($smtpserver,$smtpserverport,true,$smtpuser,$smtppass);//这里面的一个true是表示使用身份验证,否则不使用身份验证.

    $smtp->debug = FALSE;//是否显示发送的调试信息 FALSE or TRUE

    if($smtp->sendmail($smtpemailto, $smtpusermail, $mailsubject, $utfmailbody, $mailtype))
    {
    echo '邮件发送成功!';
    }else
    {
    echo '邮件发送失败!';
    }
    }
    }
    add_action('comment_post', 'comment_mail_notify');

    上面的代码仍到任何可以执行中就ok了,如主题的functions.php中。

    吵吵微信朋友圈,请付款实名加入:

    吵吵 吵吵

    4条回应:“wp使用socket和smtp代理发送评论回复邮件”

    1. 七小罗汉说道:

      好长的代码,虽然看不懂,但还是支持了

    2. 流氓兔足迹说道:

      没用WP,所以学习了!

    3. 黄镇说道:

      完全看不懂啊,,,还是支持下

    4. 蓝色离子说道:

      讲清楚点额,,不懂怎么弄额!

    发表评论

    电子邮件地址不会被公开。 必填项已用*标注