PHP调用Python发送邮件

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 "[email protected],[email protected]".
            -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 发件人,'[email protected]' 或者修改发件人名 'CleverCode<[email protected]>'
     * @param string $toAddress 收件人,多个收件人逗号分隔,'[email protected],[email protected],[email protected]', 或者 'test1<[email protected]>,test2<[email protected]>,....'
     * @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 = '[email protected]';
        // 登录密码
        $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<[email protected]>';

        // 接收者
        $toAddress = '[email protected]';

        // 标题
        $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

时间: 2024-08-28 10:37:22

PHP调用Python发送邮件的相关文章

python发送邮件(一)

最近设计了一个小的应用程序,主要是根据文件中邮件地址发送一份excel中内容,并且在接受方收到邮件都是以网页的格式呈现的. 下面主要是对python发送邮件涉及到的部分知识点做个总结 一.先介绍一下Smtp协议和POP3协议 SMTP (Simple Mail Transfer Protocol) http://www.rfc-editor.org/info/rfc821    RFC821文档详细描述了这个协议信息: 邮件传送代理 (Mail Transfer Agent,MTA) 程序使用S

解读Python发送邮件

解读Python发送邮件 Python发送邮件需要smtplib和email两个模块.也正是由于我们在实际工作中可以导入这些模块,才使得处理工作中的任务变得更加的简单.今天,就来好好学习一下使用Python发送邮件吧. SMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件.HTML邮件以及带附件的邮件. Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件. 1.邮件正文是文本的格式 1 # -*- codi

python 发送邮件例子

想到用python发送邮件 主要是服务器 有时候会产生coredump文件  ,然后因为脚本重启原因,服务器coredump产生后会重启 但是没有主动通知开发人员 想了下可以写个脚本一旦产生coredump文件就可以发送邮件给开发者让其立马知道 下面只介绍简单的发送脚本 如果需要在生产环境用起来  还需要按要求修改脚本 smtplib.SMTP([host[, port[, local_hostname[, timeout]]]]) SMTP类构造函数,表示与SMTP服务器之间的连接,通过这个连

Python发送邮件(常见四种邮件内容)

Python发送邮件(常见四种邮件内容) 转载 2017年03月03日 17:17:04 转自:http://lizhenliang.blog.51cto.com/7876557/1875330 在写脚本时,放到后台运行,想知道执行情况,会通过邮件.SMS(短信).飞信.微信等方式通知管理员,用的最多的是邮件.在linux下,Shell脚本发送邮件告警是件很简单的事,有现成的邮件服务软件或者调用运营商邮箱服务器. 对于Python来说,需要编写脚本调用邮件服务器来发送邮件,使用的协议是SMTP.

C++调用Python浅析

环境 VS2005Python2.5.4 Windows XP SP3 简述 一般开发过游戏的都知道Lua和C++可以很好的结合在一起,取长补短,把Lua脚本当成类似动态链接库来使用,很好的利用了脚本开发的灵活性.而作为一门流行的通用型脚本语言python,也是可以做到的.在一个C++应用程序中,我们可以用一组插件来实现一些具有统一接口的功能,一般插件都是使用动态链接库实现,如果插件的变化比较频繁,我们可以使用Python来代替动态链接库形式的插件(堪称文本形式的动态链接库),这样可以方便地根据

C#调用python文件执行

我的电脑环境是使用.net framework4.5.1,如果在调试过程中调不通请注意 我用的是Visual studion 2017,python组件下载地址:http://ironpython.codeplex.com/releases/view/ 下载的版本是2.7,下载安装完之后记得引入安装路径下的以下三个dll (1)首先先说一个简单的功能,在c#代码中执行python字符串,内容如下: (2)c#调用python文件: 在当前目录下新建一个后缀名为py的文件,文件名为AmoutDis

【转载】python发送邮件实例

本文转自:http://www.cnblogs.com/lonelycatcher/archive/2012/02/09/2343463.html 这几天要用python发送邮件,上网找到这篇文章感觉蛮全面的,故转载收藏之. 1. 文件形式的邮件 #!/usr/bin/env python3 #coding: utf-8 import smtplib from email.mime.text import MIMEText from email.header import Header send

编程:C#调用Python模块

当下,C#与Python都是比较热门的计算机编程语言,他们各有优缺点,如果能让他们互相配合工作,那是多么美好的事情,今天我来讲解一下如何利用C#来调用Python. 如果让C#支持调用Python模块,我们首先需要安装一些扩展,这里推荐使用IronPython库. 第一步,我们需要下载IronPython库的安装包,这里请大家移步官网 http://ironpython.codeplex.com/ ,下载并安装相关库文件. 第二步,我们新建一个C#控制台测试项目,并将IronPython安装目录

使用c语言调用python小结

最近在做一个漏洞展示平台,攻击实现部分使用python实现,c语言实现部分使用libcli库做一个类似telnet的东东,回调函数run的时候调用python模块.针对c调用python,做个了小demo python模块:demo.py def print_arg(str): print str def add(a,b): print 'a=', a print 'b=', b return a + b class Class_A: def __init__(self): print "ini