【一】概论

(1)简介:

这里说的邮件不是平时说的email邮件(邮件地址带有@符号的),而是指的一般论坛网站的站内信息,也叫私信或者pm(private message私信)

【二】站内信案例

(1)站内信构成:邮件的发送(写邮件)、邮件的接收(收件箱)、邮件的发件箱(发送的邮件列表)

(2)准备工作:

①数据表:sp_email

SQL语句:①后面的comment为注释,方便开发人员分辨;②附件这里数据库设计为只能上传一个附件

create table sp_email(
id int(11) not null auto_increment,
from_id int(11) not null comment'发送者id',
to_id int(11) not null comment'接收者id',
title varchar(50) not null comment'标题',
file varchar(255) default null comment'文件', //完整路径
hasfile smallint(1) default '0' comment'是否有附件', //有文件为1,没有文件为0.默认0(没有附件)
filename varchar(255) default null comment'文件原始名',
content text comment'内容',
addtime int(11) default null comment'添加时间', //发送时间
isread smallint(1) default '0' comment'是否已读', //是否已读,回值
primary key(id)
)engine=myisam auto_increment=1 default charset=utf8;

②修改模板文件index.html,创建导航菜单(发邮件、邮件收件箱、已发邮件)

         <li>
<a href="javascript:;" class="emailManage">邮件管理</a>
<ul>
<li><a href="{:U('Email/send')}" class="documentManage">发邮件</a></li>
<li><a href="{:U('Email/sendBox')}" class="documentManage">发件箱</a></li>
<li><a href="{:U('Email/recBox')}" class="documentManage">收件箱</a></li>
</ul>
</li>

③创建控制器EmailController.class.php

<?php
namespace Admin\Controller;
use Think\Controller;
class EmailController extends Controller{
}
?>

(3)邮件发送

分析

控制器:EmailController.class.php

方法:send(二合一,展示模板和数据保存)

模板:send.html

下面分步操作:

第一步:创建send方法,展示模板页面

<?php
namespace Admin\Controller;
use Think\Controller;
class EmailController extends Controller{
//send方法,展示模板+数据保存
public function send(){
$this->display();
}
}
?>

第二步:将send.html模板文件复制到指定目录下Application\Admin\View\Email\send.html,并替换静态资源路径

第三部:改写send方法,查询收件人,在模板中列出收件人列表

//send方法,展示模板+数据保存
public function send(){
//查询收件人信息,除去自己(id与session('id')相等的),因为自己不可以发送给自己
$data = M('user')->field('id,truename')->where('id != '.session('id'))->select();
$this->assign('data',$data);
$this->display();
}

第四步:在模板里展示收件人列表

第五步:检查表单,表单完整代码

<form action="" method="post" enctype="multipart/form-data">
<fieldset>
<legend>发送邮件</legend>
<p>
<label for="to_id">收件人:</label>
<select name="to_id" id="to_id">
<option value="0">请选择收件人</option>
<volist name="data" id="vol">
<option value="{$vol.id}">{$vol.truename}</option>
</volist>
</select>
</p>
<p><label for="title">标题:</label><input type="text" name="title" id="title"></p>
<p><label for="file">附件:</label><input type="file" name="file" id="file"></p>
<p><label for="author">内容:</label><textarea name="content"></textarea></p>
<div>
<a href="javascript:;" id="submitBtn">提交</a>
<a href="javascript:;" id="resetBtn">清空</a>
</div>
</fieldset>
</form>

第六步:将提交数据保存到数据表

先判断请求类型,若为POST请求,则处理数据,否则展示数据和模板页面。先将大概结构写出来

public function send(){
//判断请求类型
if (IS_POST) {
//接收数据
$post = I('post.');
//实例化自定义模型
$model = D('Email');
//调用具体类的方法实现数据的保存
$result = $model -> addData($post,$_FILES('file'));
if($result){
$this->success('邮件发送成功',U('sendBox'),3);
}else{
$this->error('邮件发送失败');
} }else{
//查询收件人信息,除去自己(id与session('id')相等的)
$data = M('user')->field('id,truename')->where('id != '.session('id'))->select();
$this->assign('data',$data);
$this->display();
}
}

第七步:创建自定义模型EmailModel.class.php,添加保存方法addData。先列出自定义模型的方法架构

<?php
namespace Admin\Model;
use Think\Model;
class EmailModel extends Model{
public function addData($post,$file){
}
}
?>

第八步:编写需要的addData方法实现数据处理和保存入库(文件处理+数据处理)

//文件分为文件+字符
if(!$file['error']){//判断是否有文件上传
//1. 配置数组,定义配置
$cfg = array(
//配置上传路径
'rootPath' => WORKING_PATH . UPLOAD_ROOT_PATH
);
//2. 实例化上传类
$upload = new \Think\Upload($cfg);
//3. 上传操作,并接受上传结果
$info = $upload->uploadOne($file);
dump($info);die;
}else{ }

先判断上传是否成功,上传成功的话会输出有9个元素的一维数组

接下来判断是否上传成功,若成功则继续处理补全字段。完整代码

<?php
namespace Admin\Model;
use Think\Model;
class EmailModel extends Model{
public function addData($post,$file){
//文件分为文件+字符
if(!$file['error']){//判断是否有文件上传
//1. 配置数组,定义配置
$cfg = array(
//配置上传路径
'rootPath' => WORKING_PATH . UPLOAD_ROOT_PATH
);
//2. 实例化上传类
$upload = new \Think\Upload($cfg);
//3. 上传操作,并接受上传结果
$info = $upload->uploadOne($file);
if ($info) {//成功后补全字段
//处理数据表中需要的字段file、hasfile、filename
$post['file'] = UPLOAD_ROOT_PATH . $info['savepath'] . $info['savename'];//文件在磁盘上的存储路径
$post['hasfile'] = 1;//表示是否有文件,能走进来说明肯定有文件,所以为1
$post['filename'] = $info['name'];//文件的原始名称
}else{}
// 补全字段from_id和addtime
$post['from_id'] = session('id');//发件人id
$post['addtime'] = time();//发送时间
//数据保存
return $this->add($post);
}else{ }
}
}
?>

效果图:

数据成功保存到数据表

(4)发件箱

分析:

控制器:EmailController.class.php

方法:sendBox

模板:sendBox.html

下面分步进行

第一步:创建方法sendBox,获取列表数据展示数据和模板文件

注意:发件箱里需要显示出收件人的名字(数据表里存的是from_id收件人的id,所以需要联表查询数据)

主表:sp_email(别名t1) ;从表:sp_user(别名t2)

联表条件:t1.to_id = t2.id

原生SQL:(两个方法table和join,table相当于join的inner内联,这里用table)

注意:table方法后跟两个表名,join方法后跟一个表名(左联)

select t1.*,t2.truename as truename from sp_email as t1 left join sp_user as t2 on t1.to_id=t2.id where t1.from_id=当前用户id;

将上述SQL代码复制到Navicate中执行结果

接下来参考上述代码到ThinkPHP里去执行连贯操作,然后输出打印下查询结果

浏览器测试后,显示出查询数据。接着将数据传递给模板,代码

//sendBox方法,发件箱
public function sendBox(){
//联表查询当前用户已经发送的邮件
$data = M('Email')->field('t1.*,t2.truename as truename')->alias('t1')->join('left join sp_user as t2 on t1.to_id=t2.id')->
where('t1.from_id = '.session('id'))->select();
$this->assign('data',$data);
$this->display();
}

第二步:复制模板文件sendBox.html到指定位置,并换掉静态资源路径

<table border="1" cellspacing="0" cellpadding="10">
<thead>
<tr><td>序号</td><td>收件人</td><td>标题</td><td>附件</td><td>内容</td><td>发送时间</td><td>状态</td><td>操作</td></tr>
</thead>
<volist name="data" id="vol">
<tr>
<td>{$vol.id}</td>
<td>{$vol.truename}</td>
<td>{$vol.title|msubstr=###,0,10}</td>
<td>{$vol.filename|msubstr=###,0,16}
<notempty name="vol.filename"><a href="__CONTROLLER__/download/id/{$vol.id}">【下载】</a></notempty>
</td>
<td>{$vol.content|msubstr=###,0,10}</td>
<td>{$vol.addtime|date='Y-m-d H:i:s',###}</td>
<td>
<if condition="$vol.isread == 0"><span style="color:red">未读</span><else/><span style="color:green">已读</span></if>
</td>
<td>
<a href="javascript:;" class="showBtn" data="{$vol.id}"" data-title="{$vol.title}">查看</a> |
<a href="__CONTROLLER__/edit/id/{$vol.id}" class="editBtn">删除</a>
</td>
</tr>
</volist>
</table>

显示效果:

注意:

1. 为了区别读取状态,这里我需要加判断。如果isread为0则表示未读,否则表示已读;

          2. 为了测试效果,我去Navicate里将isread手动修改为1,然后刷新浏览器测试(为了直观,可以在模板里加上颜色)

第三步:添加附件下载功能

//download下载附件
public function download(){
//接收id
$id = I('get.id');
//查询数据
$data = M('Email') -> find($id);
//下载代码,主要需要的是路径,接下来拼接路径
$file = WORKING_PATH . $data['file'];
//输出文件
header("Content-type: application/octet-stream");//文件流,告诉浏览器输出的东西是文件流
header('Content-Disposition: attachment; filename="' . basename($file) . '"');//文件名
header("Content-Length: ". filesize($file));//文件大小
//输出缓冲区
readfile($file);
}

ThinkPHP---TP功能类之邮件的更多相关文章

  1. thinkphp框架调用类不存在的方法

    thinkphp框架调用类不存在的方法调用类不存在的方法,不会报错,但是也不会执行,这是根据tp框架里面的一个魔术方法,框架里面一共才十几个魔术方法

  2. 修改ThinkPHP的验证码类

    今天用ThinkPHP重新开发一个系统,用到了ThinkPHP的验证码类,由于我希望验证码别太复杂,希望验证码里边只有数字,却发现该Verify类并未提供设置验证码中使用的字符的配置的方法,于是查看源 ...

  3. thinkphp杂项功能(主干)

    thinkphp杂项功能(主干) 一.总结 1.杂项功能:杂项里面我需要有点印象的是五个:缓存,多语言,图像处理,文件处理,单元测试 二.thinkphp杂项功能(主干) thinkphp扩展杂项功能 ...

  4. SQLSERVER监控复制并使用数据库邮件功能发告警邮件

    SQLSERVER监控复制并使用数据库邮件功能发告警邮件 最近熬出病来了,都说IT行业伤不起,不说了,说回今天的正题 正题 上个月月底的时候因为要搬迁机房,需要将一个数据信息数据库先搬到我们的机房,然 ...

  5. 【socket】Socket的三个功能类TCPClient、TCPListener 和 UDPClient

    Socket的三个功能类TCPClient.TCPListener 和 UDPClient (转) 应用程序可以通过 TCPClient.TCPListener 和 UDPClient 类使用传输控制 ...

  6. php之框架增加日志记录功能类

    <?php /* 思路:给定文件,写入读取(fopen ,fwrite……) 如果大于1M 则重写备份 传给一个内容, 判断大小,如果大于1M,备份 小于则写入 */ class Log{ // ...

  7. ThinkPHP登录功能的实现方法

    登陆功能是PHP程序设计中常见的功能.本文ThinkPHP实例主要完成注册成功后进入首页,并告诉你是登录用户的功能.具体实现步骤如下: 第一步:在config.php文件中加上: 完整实现代码如下: ...

  8. thinkphp Auth认证类 比RBAC更好的权限认证方式(Auth类认证)

    thinkphp Auth认证类 比RBAC更好的权限认证方式(Auth类认证)    Auth 类已经在ThinkPHP代码仓库中存在很久了,但是因为一直没有出过它的教程, 很少人知道它, 它其实比 ...

  9. php之ThinkPHP的memcached类的修改

    php之ThinkPHP的memcached类的修改 在Think\Cache\Driver\Memcached.class.php中,增加方法获取错误信息的方法,方便调试, public funct ...

随机推荐

  1. ≪统计学习精要(The Elements of Statistical Learning)≫课堂笔记(三)

    照例文章第一段跑题,先附上个段子(转载的哦~): I hate CS people. They don't know linear algebra but want to teach projecti ...

  2. vim note(5)

    .vimrc 的设置 $HOME/.vimrc 的普通设置,例如以下. set nocompatible "" not compatible with VI "" ...

  3. Zend Studio配置Xdebug

    按照网上的教程一直没有配置好,上官网看到一句话, If you don't know which one you need, please refer to the custom installati ...

  4. mysql对表列数和行大小的限制

    mysql对表列数和行大小的限制 - CSDN博客 https://blog.csdn.net/Dr_Joseph/article/details/78111312

  5. 【OI】指针线段树&指针

    对于线段树,我们一般需要n*4的空间去存储线段树,然后有一种玄学操作是用指针来实现线段树. #include <inttypes.h> #include <algorithm> ...

  6. POJ 1060:Modular multiplication of polynomials

    Modular multiplication of polynomials Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 4 ...

  7. 利用JFreeChart生成区域图 (5) (转自 JSP开发技术大全)

    利用JFreeChart生成区域图 (5) (转自 JSP开发技术大全) 14.5 利用JFreeChart生成区域图 通过JFreeChart插件只能生成普通效果的区域图,利用工厂类ChartFac ...

  8. 列表渲染v-for

    v-for我们用v-for指令根据一组数据的选项列表进行渲染.v-for指令需要以item in items形式的特殊语法,items是源数据数组并且item是数组元素迭代的别名. demo: < ...

  9. DNS的主从、子域授权和转发服务器

    DNS的主从.子域授权和转发服务器 主从DNS 注意: 1.全局配置options{} 里面的内容,其中 listen-on port 53 {any or local:}:或者直接注释掉,或删掉 a ...

  10. 关于Jedis无法连接上Linux上Redis问题

    环境:CentOS7.Redis 主要解决Jedis客户端无法连接Linux上Redis服务问题 1.修改Redis目录下的redis.conf配置文件 注释掉bind本地回环地址:bind 127. ...