PHP发送邮件之SMTP类

使用PHP发送邮件,可以使用内置函数mail(),但是使用mail()函数发送邮件,就必须自己配置一台不需要验证的SMTP服务器。这样的话很麻烦.下面,我们是用另外一种方式,使用封装SMTP协议的邮件类发送邮件,需要引入PHPMailer和SMTP类。

本文将以通过邮箱找回密码这样一个实例来详细介绍邮件发送操作步骤,PHP框架使用thinkPHP 3,其它框架也可按照步骤引用.为了突出主题,代码已尽可能简化。

准备工作

首先要有个邮箱账号,这里以网易邮箱为例.接下来开启 POP3/SMTP/IMAP 服务,点击邮箱里的设置,选择POP3/SMTP/IMAP.按提示一步步操作。

ChangePwd控制器

通常点击通过邮件找回密码,会跳到邮箱输入页面,下面是相应的控制器。


<?php
namespace Home\Controller;
use Think\Controller;

class ChangePwdController extends Controller {
    
    //通过邮箱找回密码
    public function findByEmail()
    {
        $this -> display();
    }

    //邮件链接点击后跳转到修改密码页面
    public function editPwdByMail()
    {
        $_SESSION ['emailpwd'] = array (
            'key'  => trim($_GET ['key']),
            'info' => trim($_GET ['info']),
            'code' => trim($_GET ['code']),
            'time' => trim($_GET ['time'])
        );
        $this->display();
    }

    //邮箱修改密码的功能实现
    public function doEditPwdByEmail()
    {
        $str = base64_decode($_SESSION['emailpwd']['info']);
        $arr = explode('+',$str); //用户名和key
        $user['username'] = $arr[0];
        $reinfo = M('user') ->where($user) -> find();
        // 判断是否在有效期,用时间戳判断或SESSION有效期判断,这里为30分钟
        $retime = time();
        if(($_SESSION['emailpwd']['code'] == md5('mytime'.$_SESSION['emailpwd']['time'])) && ((($_SESSION['emailpwd']['time']) + (60 * 30)) >= $retime)){
            if (md5($reinfo['username'].'+'.$reinfo['password']) == $_SESSION['emailpwd']['key']){ // 判断URL传输中username是否更改
                $upid ['id'] = $reinfo ['id'];
                if($_POST ['user_password'] == $_POST ['reuser_password'] && $_POST ['user_password'] != '') {
                    $data['password'] = md5(trim(I('post.reuser_password')));
                    $edit = M('user') -> where($upid) -> data($data) -> save();
                    if($edit){
                        unset($_SESSION ['emailpwd']);
                        $this -> success('修改成功,请重新登录!!',U( 'Index/index' ),2);
                    }else{
                        $this -> error('修改失败!!');
                    }
                }else{
                    $this -> error('两次输入密码不一致,或者密码为空!');
                    exit();
                }
            }else{
                //链接被更改
                $this -> error('链接出现错误或密码已经修改,请重试!!',U('Email/index'),3);
            }
        }else{
            //超过30分钟,无效链接,删除这个session
            unset($_SESSION ['emailpwd']);
            $this -> error('链接失效,请重新申请',U('Email/index'),2);
        }
    }
}
    

findByEmail模板

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>密码找回</title>
    </head>
    <body>
        <form action="{:U('Email/SendEmail')}" method="post">
            邮箱地址:<input type="text" name='email'><br>
            <input type="submit" value="提交">
        </form>
    </body>
</html>

然后是后台逻辑代码

Email控制器

<?php 
     namespace Home\Controller; 
     use Think\Controller; 

     class EmailController extends Controller { 
         //发送邮件 
         public function SendEmail() 
         { 
             $map['email'] = I('post.email'); 
             $info = M('user') -> where($map) -> find(); //查询信息是否存在 
             if($info){ 
                       $key = md5($info['username'].'+'.$info['password']); 
                       $string = base64_encode($info['username'].'+'.$key); // 加密,可解密 
                       $time = time(); 
                       $code = md5('mytime'.$time); 
                       // 生成URL 
                       $findpwd = $_SERVER['HTTP_HOST'].U('ChangePwd/editPwdByMail').'?key='.$key.'&info='.$string.'&time='.$time.'&code='.$code; // code是用来检验time是否有修改过 
                       $username = $info['username']; 
                       $title = "找回密码"; 
                       $content = "<h3>亲爱的:$username 用户</h3> <br><br>http:
                       //$findpwd 
                       <br><br><br><h4>有效期30分钟</h4> <br><br>"; 
                       $from = "发件方邮箱地址"; //修改为自己的发送邮箱 
                       $to = $info['email']; 
                       // 调用发送邮件函数 
                       $status = send_mail($title,$content,$from,$to); 
                       if($status == 1){ 
                               $this -> success ('发送邮件成功...','',2); 
                           }else{ 
                               $this -> error('发送邮件失败...'); 
                               exit(); 
                           } 
                       }else{ 
                           $this -> error('此邮箱未注册'); 
                           exit(); 
                       } 
            }
     }

接下来是send_mail()函数

send_mail()


//邮件的配置函数
function send_mail($title,$content,$from,$to,$chart = 'utf-8',$attachment = '') {
    import('Common.Util.Email.PHPMailer');
    import('Common.Util.Email.SMTP');

    $mail = new PHPMailer();
    $mail -> CharSet = $chart; // 设置编码
    $mail -> IsSMTP('smtp'); // 设置采用SMTP方式发送邮件
    $mail -> Host = "smtp.163.com"; // 设置邮件服务器的地址(例如网易邮箱)
    $mail -> Port = 25; // 设置邮件服务器的端口,SMTP默认为25
    $mail -> From = $from; // 设置发件人的邮箱地址
    $mail -> FromName = "Leon"; // 设置发件人的姓名
    $mail -> SMTPAuth = true; // 设置SMTP是否需要密码验证,true表示需要
    $mail -> Username = "发件方的邮箱"; // 设置发送邮件的邮箱
    $mail -> Password = "邮箱密码"; // 设置邮箱的密码,可以是独立密码
    $mail -> Subject = $title; // 设置邮件的标题
    $mail -> AltBody = "text/html";
    $mail -> Body = $content; // 设置邮件内容
    $mail -> IsHTML (true); // 设置内容是否为html类型
    $mail -> WordWrap = 50; // 设置每行的字符数
    $mail -> AddReplyTo ("地址","名字"); // 设置回复的收件人的地址
    $mail -> AddAddress ( $to,"" ); // 设置收件的地址
    if($attachment != ''){
        $mail->AddAttachment($attachment,$attachment);
    }

    if ($mail -> Send()){
        //$status1 = "$to" . '&nbsp;&nbsp;已投送成功<br />';
        $status = 1;
    }else{
        //$status2 = "$to" . '&nbsp;&nbsp;发送邮件失败<br />';
        $status = 0;
    }
    return $status;
}
    

前面说的两个类现在派上用场了,在Thinkphp框架中,请不要改变核心目录ThinkPHP,我们将外部类放在应用目录下,如图所示

类文件下载

PHPMailer下载   SMTP下载

如果操作成功,那么应该就能收到邮件了,邮件里是一个链接,有效期为30分钟(可自行设定),点击链接将访问ChangePwd控制器editPwdByMail方法

editPwdByMail模板

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>通过邮箱设置密码</title>
    <style type="text/css"> #all{ width:550px; height:auto; overflow: hidden; margin:0 auto; } td{ font-size:14px; } input{ border:solid 1px #ddd; width:200px; height:24px; } table,td{ border-collapse: collapse; padding:10px; } span{ font-size:12px; color:green; display:none; } .active{ border:solid 1px blue; } .error{ border:solid 1px red; } .error-text { color:red; } .success-text{ color:green; } </style>
</head>
<body>
    <div>邮箱验证成功,请输入新密码。</div>
    <div id="all">
        <form action="{:U('ChangePwd/doEditPwdByEmail')}" method="post">
            <table>
                <tr><td>密码</td><td><input remind="请输入6~20位的非空白字符" type="password" name="user_password"><span></span></td></tr>
                <tr><td>确认密码</td><td><input type="password" remind="请再次输入密码" name="reuser_password"><span></span></td></tr>
                <tr><td></td><td><button>点击提交</button></td></tr>
            </table>
        </form>
    </div>

    <script type="text/javascript" src="__PUBLIC__/js/jquery-1.9.0.min.js"></script>
    <script language="javascript"> //检测变量的声明 var CPASS = false; var CREPASS = false; //绑定获得焦点事件 $('input').focus(function(){ //获取当前元素中remind属性 var remind = $(this).attr('remind'); //显示 $(this).next().html(remind).removeClass().addClass('success-text').show(); //修改元素的边框 $(this).addClass('active'); }); //绑定密码的丧失焦点事件 $('input[name=user_password]').blur(function(){ //获取密码的值 var v = $(this).val(); //声明正则 var reg = /^\S{6,20}$/; //检测 var res = reg.test(v); if(!res){ $(this).next().html('密码格式不正确').removeClass().addClass('error-text').show(); $(this).removeClass().addClass('error'); CPASS = false; }else{ $(this).next().html('√').removeClass().addClass('success-text'); $(this).removeClass(); CPASS = true; } }); //确认密码的丧失焦点事件 $('input[name=reuser_password]').blur(function(){ //获取密码的值 var v = $(this).val(); //检测 var res = $('input[name=user_password]').val() == v; if(!res){ $(this).next().html('两次密码不一致').removeClass().addClass('error-text').show(); $(this).removeClass().addClass('error'); CREPASS = false; }else{ $(this).next().html('').removeClass().addClass('success-text'); $(this).removeClass(); CREPASS = true; } }); //表单提交事件的绑定 $('form').submit(function(){ //触发元素的丧失焦点事件 $('input[name=user_password]').trigger('blur'); $('input[name=reuser_password]').trigger('blur'); //检测元素的值 if(CPASS && CREPASS){ return true; } return false; }); </script>
</body>
</html>

至此,密码已修改完成,发送邮件操作就介绍到这里。

发表评论

发表回复

沙发空缺中,还不快抢~