PHP调用Python快速发送高并发邮件
off999 2024-12-12 14:24 17 浏览 0 评论
1 简介
在PHP中发送邮件,通常都是封装一个php的smtp邮件类来发送邮件。但是PHP底层的socket编程相对于python来说效率是非常低的。CleverCode同时写过用python写的爬虫抓取网页,和用php写的爬虫抓取网页。发现虽然用了php的curl抓取网页,但是涉及到超时,多线程同时抓取等等。不得不说python在网络编程的效率要比PHP好的多。
PHP在发送邮件时候,自己写的smtp类,发送的效率和速度都比较低。特别是并发发送大量带有附件报表的邮件的时候。php的效率很低。建议可以使用php调用python的方式来发送邮件。
2 程序
2.1 python程序
php的程序和python的文件必须是相同的编码。如都是gbk编号,或者同时utf-8编码,否则容易出现乱码。python发送邮件主要使用了email模块。这里python文件和php文件都是gbk编码,发送的邮件标题内容与正文内容也是gbk编码。
#!/usr/bin/python
# -*- coding:gbk -*-
"""
邮件发送类
"""
# mail.py
#
# Copyright (c) 2014 by http://blog.csdn.net/CleverCode
#
# modification history:
# --------------------
# 2014/8/15, by CleverCode, Create
import threading
import time
import random
from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email import Utils, Encoders
import mimetypes
import sys
import smtplib
import socket
import getopt
import os
class SendMail:
def __init__(self,smtpServer,username,password):
"""
smtpServer:smtp服务器,
username:登录名,
password:登录密码
"""
self.smtpServer = smtpServer
self.username = username
self.password = password
def genMsgInfo(self,fromAddress,toAddress,subject,content,fileList,\
subtype = 'plain',charset = 'gb2312'):
"""
组合消息发送包
fromAddress:发件人,
toAddress:收件人,
subject:标题,
content:正文,
fileList:附件,
subtype:plain或者html
charset:编码
"""
msg = MIMEMultipart()
msg['From'] = fromAddress
msg['To'] = toAddress
msg['Date'] = Utils.formatdate(localtime=1)
msg['Message-ID'] = Utils.make_msgid()
#标题
if subject:
msg['Subject'] = subject
#内容
if content:
body = MIMEText(content,subtype,charset)
msg.attach(body)
#附件
if fileList:
listArr = fileList.split(',')
for item in listArr:
#文件是否存在
if os.path.isfile(item) == False:
continue
att = MIMEText(open(item).read(), 'base64', 'gb2312')
att["Content-Type"] = 'application/octet-stream'
#这里的filename邮件中显示什么名字
filename = os.path.basename(item)
att["Content-Disposition"] = 'attachment; filename=' + filename
msg.attach(att)
return msg.as_string()
def send(self,fromAddress,toAddress,subject = None,content = None,fileList = None,\
subtype = 'plain',charset = 'gb2312'):
"""
邮件发送函数
fromAddress:发件人,
toAddress:收件人,
subject:标题
content:正文
fileList:附件列表
subtype:plain或者html
charset:编码
"""
try:
server = smtplib.SMTP(self.smtpServer)
#登录
try:
server.login(self.username,self.password)
except smtplib.SMTPException,e:
return "ERROR:Authentication failed:",e
#发送邮件
server.sendmail(fromAddress,toAddress.split(',') \
,self.genMsgInfo(fromAddress,toAddress,subject,content,fileList,subtype,charset))
#退出
server.quit()
except (socket.gaierror,socket.error,socket.herror,smtplib.SMTPException),e:
return "ERROR:Your mail send failed!",e
return 'OK'
def usage():
"""
使用帮助
"""
print """Useage:%s [-h] -s <smtpServer> -u <username> -p <password> -f <fromAddress> -t <toAddress> [-S <subject> -c
<content> -F <fileList>]
Mandatory arguments to long options are mandatory for short options too.
-s, --smtpServer= smpt.xxx.com.
-u, --username= Login SMTP server username.
-p, --password= Login SMTP server password.
-f, --fromAddress= Sets the name of the "from" person (i.e., the envelope sender of the mail).
-t, --toAddress= Addressee's address. -t "test@test.com,test1@test.com".
-S, --subject= Mail subject.
-c, --content= Mail message.-c "content, ......."
-F, --fileList= Attachment file name.
-h, --help Help documen.
""" %sys.argv[0]
def start():
"""
"""
try:
options,args = getopt.getopt(sys.argv[1:],"hs:u:p:f:t:S:c:F:","--help --smtpServer= --username= --password= --fromAddress= --toAddress= --subject= --content= --fileList=",)
except getopt.GetoptError:
usage()
sys.exit(2)
return
smtpServer = None
username = None
password = None
fromAddress = None
toAddress = None
subject = None
content = None
fileList = None
#获取参数
for name,value in options:
if name in ("-h","--help"):
usage()
return
if name in ("-s","--smtpServer"):
smtpServer = value
if name in ("-u","--username"):
username = value
if name in ("-p","--password"):
password = value
if name in ("-f","--fromAddress"):
fromAddress = value
if name in ("-t","--toAddress"):
toAddress = value
if name in ("-S","--subject"):
subject = value
if name in ("-c","--content"):
content = value
if name in ("-F","--fileList"):
fileList = value
if smtpServer == None or username == None or password == None:
print 'smtpServer or username or password can not be empty!'
sys.exit(3)
mail = SendMail(smtpServer,username,password)
ret = mail.send(fromAddress,toAddress,subject,content,fileList)
if ret != 'OK':
print ret
sys.exit(4)
print 'OK'
return 'OK'
if __name__ == '__main__':
start()
2.2 python程序使用帮助
输入以下命令,可以输出这个程序的使用帮助
# python mail.py --help
2.3 php程序
这个程序主要是php拼接命令字符串,调用python程序。注意:用程序发送邮件,需要到邮件服务商,开通stmp服务功能。如qq就需要开通smtp功能后,才能用程序发送邮件。开通如下图。
php调用程序如下:
<?php
/**
* SendMail.php
*
* 发送邮件类
*
* Copyright (c) 2015 by http://blog.csdn.net/CleverCode
*
* modification history:
* --------------------
* 2015/5/18, by CleverCode, Create
*
*/
class SendMail{
/**
* 发送邮件方法
*
* @param string $fromAddress 发件人,'clevercode@qq.com' 或者修改发件人名 'CleverCode<clevercode@qq.com>'
* @param string $toAddress 收件人,多个收件人逗号分隔,'test1@qq.com,test2@qq.com,test3@qq.com....', 或者 'test1<test1@qq.com>,test2<test2@qq.com>,....'
* @param string $subject 标题
* @param string $content 正文
* @param string $fileList 附件,附件必须是绝对路径,多个附件逗号分隔。'/data/test1.txt,/data/test2.tar.gz,...'
* @return string 成功返回'OK',失败返回错误信息
*/
public static function send($fromAddress, $toAddress, $subject = NULL, $content = NULL, $fileList = NULL){
if (strlen($fromAddress) < 1 || strlen($toAddress) < 1) {
return '$fromAddress or $toAddress can not be empty!';
}
// smtp服务器
$smtpServer = 'smtp.qq.com';
// 登录用户
$username = 'clevercode@qq.com';
// 登录密码
$password = '123456';
// 拼接命令字符串,实际是调用了/home/CleverCode/mail.py
$cmd = "LANG=C && /usr/bin/python /home/CleverCode/mail.py";
$cmd .= " -s '$smtpServer'";
$cmd .= " -u '$username'";
$cmd .= " -p '$password'";
$cmd .= " -f '$fromAddress'";
$cmd .= " -t '$toAddress'";
if (isset($subject) && $subject != NULL) {
$cmd .= " -S '$subject'";
}
if (isset($content) && $content != NULL) {
$cmd .= " -c '$content'";
}
if (isset($fileList) && $fileList != NULL) {
$cmd .= " -F '$fileList'";
}
// 执行命令
exec($cmd, $out, $status);
if ($status == 0) {
return 'OK';
} else {
return "Error,Send Mail,$fromAddress,$toAddress,$subject,$content,$fileList ";
}
return 'OK';
}
}
2.3 使用样例
压缩excel成附件,发送邮件。
<?php
/**
* test.php
*
* 压缩excel成附件,发送邮件
*
* Copyright (c) 2015 http://blog.csdn.net/CleverCode
*
* modification history:
* --------------------
* 2015/5/14, by CleverCode, Create
*
*/
include_once ('SendMail.php');
/*
* 客户端类
* 让客户端和业务逻辑尽可能的分离,降低页面逻辑和业务逻辑算法的耦合,
* 使业务逻辑的算法更具有可移植性
*/
class Client{
public function main(){
// 发送者
$fromAddress = 'CleverCode<clevercode@qq.com>';
// 接收者
$toAddress = 'all@qq.com';
// 标题
$subject = '这里是标题!';
// 正文
$content = "您好:\r\n";
$content .= " 这里是正文\r\n ";
// excel路径
$filePath = dirname(__FILE__) . '/excel';
$sdate = date('Y-m-d');
$PreName = 'CleverCode_' . $sdate;
// 文件名
$fileName = $filePath . '/' . $PreName . '.xls';
// 压缩excel文件
$cmd = "cd $filePath && zip $PreName.zip $PreName.xls";
exec($cmd, $out, $status);
$fileList = $filePath . '/' . $PreName . '.zip';
// 发送邮件(附件为压缩后的文件)
$ret = SendMail::send($fromAddress, $toAddress, $subject, $content, $fileList);
if ($ret != 'OK') {
return $ret;
}
return 'OK';
}
}
/**
* 程序入口
*/
function start(){
$client = new Client();
$client->main();
}
start();
?>
2.4 程序源码下载
http://download.csdn.net/detail/clevercode/8711809
版权声明:
1)原创作品,出自"CleverCode的博客",转载时请务必注明以下原创地址,否则追究版权法律责任。
2)原创地址:http://blog.csdn.net/clevercode/article/details/45815453(转载务必注明该地址)。
3)欢迎大家关注我博客更多的精彩内容:http://blog.csdn.net/CleverCode。
相关推荐
- 大文件传不动?WinRAR/7-Zip 入门到高手,这 5 个技巧让你效率翻倍
-
“这200张照片怎么传给女儿?微信发不了,邮箱附件又超限……”62岁的张阿姨对着电脑犯愁时,儿子只用了3分钟就把照片压缩成一个文件,还教她:“以后用压缩软件,比打包行李还方便!”职场人更懂这...
- 电脑解压缩软件推荐——7-Zip:免费、高效、简洁的文件管理神器
-
在日常工作中,我们经常需要处理压缩文件。无论是下载软件包、接收文件,还是存储大量数据,压缩和解压缩文件都成为了我们日常操作的一部分。而说到压缩解压软件,7-Zip绝对是一个不可忽视的名字。今天,我就来...
- 设置了加密密码zip文件要如何打开?这几个方法可以试试~
-
Zip是一种常见的压缩格式文件,文件还可以设置密码保护。那设置了密码的Zip文件要如何打开呢?不清楚的小伙伴一起来看看吧。当我们知道密码想要打开带密码的Zip文件,我们需要用到适用于Zip格式的解压缩...
- 大文件想要传输成功,怎么把ZIP文件分卷压缩
-
不知道各位小伙伴有没有这样的烦恼,发送很大很大的压缩包会受到限制,为此,想要在压缩过程中将文件拆分为几个压缩包并且同时为所有压缩包设置加密应该如何设置?方法一:使用7-Zip免费且强大的文件管理工具7...
- 高效处理 RAR 分卷压缩包:合并解压操作全攻略
-
在文件传输和存储过程中,当遇到大文件时,我们常常会使用分卷压缩的方式将其拆分成多个较小的压缩包,方便存储和传输。RAR作为一种常见的压缩格式,分卷压缩包的使用频率也很高。但很多人在拿到RAR分卷...
- 2个方法教你如何删除ZIP压缩包密码
-
zip压缩包设置了加密密码,每次解压文件都需要输入密码才能够顺利解压出文件,当压缩包文件不再需要加密的时候,大家肯定想删除压缩包密码,或是忘记了压缩包密码,想要通过删除操作将压缩包密码删除,就能够顺利...
- 速转!漏洞预警丨压缩软件Winrar目录穿越漏洞
-
WinRAR是一款功能强大的压缩包管理器,它是档案工具RAR在Windows环境下的图形界面。该软件可用于备份数据,缩减电子邮件附件的大小,解压缩从Internet上下载的RAR、ZIP及其它类...
- 文件解压方法和工具分享_文件解压工具下载
-
压缩文件减少文件大小,降低文件失效的概率,总得来说好处很多。所以很多文件我们下载下来都是压缩软件,很多小伙伴不知道怎么解压,或者不知道什么工具更好,所以今天做了文件解压方法和工具的分享给大家。一、解压...
- [python]《Python编程快速上手:让繁琐工作自动化》学习笔记3
-
1.组织文件笔记(第9章)(代码下载)1.1文件与文件路径通过importshutil调用shutil模块操作目录,shutil模块能够在Python程序中实现文件复制、移动、改名和删除;同时...
- Python内置tarfile模块:读写 tar 归档文件详解
-
一、学习目标1.1学习目标掌握Python内置模块tarfile的核心功能,包括:理解tar归档文件的原理与常见压缩格式(gzip/bz2/lzma)掌握tar文件的读写操作(创建、解压、查看、过滤...
- 使用python展开tar包_python拓展
-
类Unix的系统,打包文件经常使用的就是tar包,结合zip工具,可以方便的打包并解压。在python的标准库里面有tarfile库,可以方便实现生成了展开tar包。使用这个库最大的好处,可能就在于不...
- 银狐钓鱼再升级:白文件脚本化实现GO语言后门持久驻留
-
近期,火绒威胁情报中心监测到一批相对更为活跃的“银狐”系列变种木马。火绒安全工程师第一时间获取样本并进行分析。分析发现,该样本通过阿里云存储桶下发恶意文件,采用AppDomainManager进行白利...
- ZIP文件怎么打开?2个简单方法教你轻松搞定!
-
在日常工作和生活中,我们经常会遇到各种压缩文件,其中最常见的格式之一就是ZIP。ZIP文件通过压缩数据来减少文件大小,方便我们进行存储和传输。然而,对于初学者来说,如何打开ZIP文件可能会成为一个小小...
- Ubuntu—解压多个zip压缩文件.zip .z01 .z02
-
方法将所有zip文件放在同一目录中:zip_file.z01,zip_file.z02,zip_file.z03,...,zip_file.zip。在Zip3.0版本及以上,使用下列命令:将所有zi...
- 如何使用7-Zip对文件进行加密压缩
-
7-Zip是一款开源的文件归档工具,支持多种压缩格式,并提供了对压缩文件进行加密的功能。使用7-Zip可以轻松创建和解压.7z、.zip等格式的压缩文件,并且可以通过设置密码来保护压缩包中的...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)