我的总体目标是限制发送到目标域的电子邮件数量(如果在要限制的数据库中设置的电子邮件)。这背后的原因是最大化从邮件服务器发送的电子邮件数量+能够根据跳出率和其他因素调整油门设置。
例如,如果我为gmail和yahoo设置节流率为'100',它将最多拉100条记录LIKE'gmail'和最多100条记录LIKE'yahoo'并继续发送它们。但是,如果没有更多受限制的域要处理,请将$ rest_max拉到$ throttle_domain并继续发送它们。问题#1 - 我如何反复循环第一个查询,直到$ throttle_domain用完为止?
问题#2 - 如何将记录拉到与油门域不匹配的位置,我将如何将其与此相关联?修改的 忘了提到下面的代码工作正常,除了它只会拉1个油门记录并停止。
$rest_max = '200';
// this is where i need to loop!?
$query = "SELECT * FROM `mailer_lists` WHERE `email` LIKE '%".$throttle_domain."' LIMIT ".$trim_speed."" ;
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)){
$email = $row['email'];
$project = $row['project_name'];
$querya = "SELECT * FROM `mailer_controller` WHERE `project_name` = '".$project."'" ;
$resulta = mysql_query($querya) or die(mysql_error());
while($rowa = mysql_fetch_array($resulta)){
$project_name = $rowa['project_name'];
$from_name = $rowa['from_name'];
$from_email = $rowa['from_name']."@".$node_domain;
$subject = $rowa['subject'];
$body = $rowa['body'];
$content = addslashes($body);
// set header
$header_from = 'From: '.$from_name.' <'.$from_email.'>';
$header_reply_to = '-f '.$from_email;
// send mail
mail($email,$subject,$body,$header_from,$header_reply_to);
// delete contact from list only if it gets sent.
mysql_query("DELETE FROM mailer_lists WHERE `project_name` = '".$project_name."' AND `email` = '$email' ") or die(mysql_error());
}}
答案 0 :(得分:3)
这应该删除不必要的循环和额外的查询,这可能无法解决您的所有答案,但可能会帮助您一路走来。
我还没有测试过这段代码,所以一定要先在测试环境中运行它,以确保我没有犯一个可能导致数据丢失的简单错误,由于查询的性质,我把它放了免责声明,首先通过测试数据进行测试。
$rest_max = '200';
$query = "SELECT *
FROM `mailer_lists` ml
JOIN `mailer_controller` mc ON ml.project_name = mc.project_name
WHERE `email` LIKE '%".$throttle_domain."' LIMIT ".$trim_speed."" ;
$result = mysql_query($query) or die(mysql_error());
$delete=array();
while($row = mysql_fetch_assoc($result)){
$email = $row['email'];
$project_name = $rowa['project_name'];
$from_name = $rowa['from_name'];
$from_email = $rowa['from_name']."@".$node_domain;
$subject = $rowa['subject'];
$body = $rowa['body'];
$content = addslashes($body);
// set header
$header_from = 'From: '.$from_name.' <'.$from_email.'>';
$header_reply_to = '-f '.$from_email;
// send mail
mail($email,$subject,$body,$header_from,$header_reply_to);
$delete[] = " (project_name = '$project_name' AND email = '$email') ";
}
if (!empty($delete)) {
mysql_query("DELETE FROM mailer_lists
WHERE " . implode(' OR ', $delete)) or die(mysql_error());
}
一种简单的测试方法是注释mail
部分并将DELETE FROM
更改为SELECT * FROM
并回显选择的内容,以确保应该使用的正确数据删除了出来。
请仔细阅读
然而,更好的删除方法是使用Tables ID
字段并将其存储在$delete
中。因为这会减轻OR
语句并最小化意外删除有效行的错误。以下是它的工作方式(只使用了结尾,将ID
替换为您的id字段:
$delete[] = $row['id'];
}
if (!empty($delete)) {
mysql_query("DELETE FROM mailer_lists
WHERE id IN(" . implode(', ', $delete) . ")") or die(mysql_error());
}
<强>更新强>
我不确定它会以多快的速度运行等等。但是一种可行的方法,而不是将它放在循环中是:
// Fill the array however you want to with the domains. this is just an example
$throttle = array('domain1.com', 'domain2.com', 'domain3.com');
$query = "SELECT *
FROM `mailer_lists` ml
JOIN `mailer_controller` mc ON ml.project_name = mc.project_name
WHERE `email` LIKE '%". implode("' OR `email` LIKE '%", $throttle) . "' LIMIT ".$trim_speed." ORDER BY project_name, email";
同样,这是未经测试的,我不确定性能如何匹配。但是有些东西供你测试。
编辑:更改为fetch_assoc
与fetch_array
答案 1 :(得分:1)
你为什么不沿着这些方式做点什么约翰:
$rest_max = '200';
$email = array();
$project = array();
$query = "SELECT * FROM `mailer_lists`, `mailer_controller` WHERE mailer_lists.project_name = mailer_controller.project_name AND `email` LIKE '%".$throttle_domain."' LIMIT ".$trim_speed."" ;
$result = mysql_query($query) or die(mysql_error());
$count = mysql_num_rows($result);
while($row = mysql_fetch_array($result)){
$email[] = $row['email'];
$project[] = $row['project_name'];
}
$rest_max = $rest_max - $count;
if($rest_max > 0)
{
//repeat the process with the new domain
}
您可以使用联接同时执行两个查询,并使用mysql_num_rows查看Select中返回的结果数量,并使用它来确定您是否已达到200个结果。你也可以把整个东西放在for循环中,但如果你只使用上面提到的2个域,这将是最好的方法
答案 2 :(得分:0)
从我看到的,你这样做:
$query = "SELECT * FROM `mailer_lists` WHERE `email` LIKE '%".$throttle_domain."' LIMIT ".$trim_speed."" ;
你可以这样做:
$query = "SELECT * FROM `mailer_lists` WHERE `email` LIKE '%$throttle_domain';";
我用内联变量(“string $ variable morestring”)替换了你的串联(“string”。$ variable。“morestring”),因为没有IDE突出显示它会更容易理解。它仍然是正确的语法,你的PHP解释器就可以了。但是对于实际的改变:遗漏了LIMIT条款。
通过移除LIMIT,您将立即返回所有内容。这是一件好事,因为这意味着每次运行脚本时都不会执行 n 查询,而是运行两个查询。它也很好,因为它可以立即为您提供所有结果。
然后你可以使用mysql_fetch_array遍历结果,或者你可以 - 这很棒 - 使用像 mysql_fetch_all 这样的函数将整个结果转换为标准数组。出于某种原因,mysql_fetch_all不是PHP MySQL模块的一部分,但实现发布在这里的评论中:
http://php.net/manual/en/function.mysql-fetch-array.php
然后您将整个搜索结果作为一个易于访问的键控数组。性感又简单。