我正在尝试为我的应用程序实现一个邮件列表系统。我目前使用Zend_Mail_Transport_Smtp('localhost')
作为传输器,遍历我的订阅者列表,并向每个订阅者发送一个新的Zend_Mail
。然而,我注意到,随着订阅者数量的增加,脚本完成所需的时间长度也会增加。
我相信肯定有更专业的方法来做这件事,包括电子邮件的排队。我认为理想的方法是让用户填写表单,单击send,然后立即得到回复,表明电子邮件正在发送,而不是等待数百封电子邮件完成发送。
我知道Zend_Mail
不做任何排序邮件排队。有经验的人能给我介绍一下如何做到这一点吗?我对cron/crontab/cronjob一无所知,所以如果涉及到这一点,请解释一下过程。
发布于 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
发布于 2009-04-25 12:49:59
对于成千上万的收件人来说,使用PHP应该没问题,不过要避免使用mail(),就像其他人提到的那样。我已经看到一些专为大量邮件(100,000+收件人)设计的系统绕过了标准邮件功能,并试图更直接地与MTA协作。即使到那时,我也不清楚这是必需的。
让电子邮件变得专业,更多的是要确保格式良好(HTML和尽可能纯文本),人们可以轻松地取消订阅,退回被正确处理,邮件服务器具有所有正确的DNS记录,并且服务器配置不违反任何主要黑名单系统的规则。编写应用程序所使用的语言并不是几百甚至几千条消息的主要因素。
https://stackoverflow.com/questions/788596
复制相似问题