首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >从Zend Framework应用程序向数百个收件人发送电子邮件的最佳方法是什么?

从Zend Framework应用程序向数百个收件人发送电子邮件的最佳方法是什么?
EN

Stack Overflow用户
提问于 2009-04-25 09:22:57
回答 2查看 12.6K关注 0票数 16

我正在尝试为我的应用程序实现一个邮件列表系统。我目前使用Zend_Mail_Transport_Smtp('localhost')作为传输器,遍历我的订阅者列表,并向每个订阅者发送一个新的Zend_Mail。然而,我注意到,随着订阅者数量的增加,脚本完成所需的时间长度也会增加。

我相信肯定有更专业的方法来做这件事,包括电子邮件的排队。我认为理想的方法是让用户填写表单,单击send,然后立即得到回复,表明电子邮件正在发送,而不是等待数百封电子邮件完成发送。

我知道Zend_Mail不做任何排序邮件排队。有经验的人能给我介绍一下如何做到这一点吗?我对cron/crontab/cronjob一无所知,所以如果涉及到这一点,请解释一下过程。

EN

回答 2

Stack Overflow用户

发布于 2011-05-26 08:07:49

使用Zend_Queue将电子邮件放入队列中,以便进行异步后台处理。您将需要一个cron作业来在后台处理队列。

protected function _enqueueEmail(WikiEmailArticle $email)
{
    static $intialized = false; 

    if (!$initialized) {

        $this->_initializeMailQueue("wikiappwork_queue");
        $initialized = true;
    }

    $this->_mailQueue->send(serialize($email));  
}
protected function _initializeMailQueue()
{
    /* See: 1.) http://framework.zend.com/manual/en/zend.queue.adapters.html and
     *      2.) Zend/Queue/Adapter/Db/mysql.sql. 
     */

 $ini = Zend_Controller_Front::getInstance()->getParam('bootstrap')
                                            ->getOptions(); 

     $queueAdapterOptions =    array( 'driverOptions' => array(
    'host' => $ini['resources']['multidb']['zqueue']['host'],
    'username' => $ini['resources']['multidb']['zqueue']['username'],
    'password' => $ini['resources']['multidb']['zqueue']['password'],
    'dbname' => $ini['resources']['multidb']['zqueue']['dbname'],
    'type' => $ini['resources']['multidb']['zqueue']['adapter'] ),
    'name' => $ini['resources']['multidb']['zqueue']['queueName'] );

    $this->_mailQueue = new Zend_Queue('Db', $queueAdapterOptions);

 }

然后,对于cron作业,脚本如下所示

<?php
use \Wiki\Email\WikiEmailArticle;

// Change this define to correspond to the location of the wikiapp.work/libary
define('APPLICATION_PATH', '/home/kurt/public_html/wikiapp.work/application');

set_include_path(implode(PATH_SEPARATOR, array(
     APPLICATION_PATH . '/../library',
     get_include_path(),
 )));

// autoloader (uses closure) for loading both WikiXXX classes and Zend_ classes.
spl_autoload_register(function ($className) { 

  // Zend classes need underscore converted to PATH_SEPARATOR
  if (strpos($className, 'Zend_' ) === 0) {

        $className = str_replace('_', '/', $className );   
  }

  $file = str_replace('\\', '/', $className . '.php');

  // search include path for the file.
  $include_dirs = explode(PATH_SEPARATOR, get_include_path());

  foreach($include_dirs as $dir) {

    $full_file = $dir . '/'. $file;

    if (file_exists($full_file)) { 

        require_once $full_file; 
        return true; 
    }
  }

  return false; 
 }); 

// Load and parese ini file, grabing sections we need.
$ini = new Zend_Config_Ini(APPLICATION_PATH . 
                          '/configs/application.ini', 'production');

$queue_config = $ini->resources->multidb->zqueue;

$smtp_config = $ini->email->smtp;

$queueAdapterOptions =  array( 'driverOptions' => array(
                                        'host'      => $queue_config->host,
                    'username'  => $queue_config->username,
                    'password'  => $queue_config->password,
                    'dbname'    => $queue_config->dbname,
                    'type'      => $queue_config->adapter),
                'name' => $queue_config->queuename);

$queue = new Zend_Queue('Db', $queueAdapterOptions);


$smtp = new Zend_Mail_Transport_Smtp($smtp_config->server, array(
                'auth'      => $smtp_config->auth,
        'username'  => $smtp_config->username,
        'password'  => $smtp_config->password,
        'port'      => $smtp_config->port,
        'ssl'       => $smtp_config->ssl
        ));

Zend_Mail::setDefaultTransport($smtp);

$messages = $queue->receive(10); 

foreach($messages as $message) {

        // new WikiEmailArticle.     
    $email = unserialize($message->body);

        try {

            $email->send();

        }  catch(Zend_Mail_Exception $e) {

               // Log the error?
               $msg = $e->getMessage();
               $str = $e->__toString();
               $trace =  preg_replace('/(\d\d?\.)/', '\1\r', $str);
        } // end try

$queue->deleteMessage($message);

} // end foreach
票数 3
EN

Stack Overflow用户

发布于 2009-04-25 12:49:59

对于成千上万的收件人来说,使用PHP应该没问题,不过要避免使用mail(),就像其他人提到的那样。我已经看到一些专为大量邮件(100,000+收件人)设计的系统绕过了标准邮件功能,并试图更直接地与MTA协作。即使到那时,我也不清楚这是必需的。

让电子邮件变得专业,更多的是要确保格式良好(HTML和尽可能纯文本),人们可以轻松地取消订阅,退回被正确处理,邮件服务器具有所有正确的DNS记录,并且服务器配置不违反任何主要黑名单系统的规则。编写应用程序所使用的语言并不是几百甚至几千条消息的主要因素。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/788596

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档