循环一个mysql查询

时间:2011-04-19 16:14:28

标签: php mysql loops

我真的真的需要一些帮助。 2天我一直被困住了。我需要一个方向来接受这个,因为我正在做的事情显然不起作用而且我感到非常沮丧。

我的总体目标是限制发送到目标域的电子邮件数量(如果在要限制的数据库中设置的电子邮件)。这背后的原因是最大化从邮件服务器发送的电子邮件数量+能够根据跳出率和其他因素调整油门设置。

例如,如果我为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());  
    }}

3 个答案:

答案 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_assocfetch_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

然后您将整个搜索结果作为一个易于访问的键控数组。性感又简单。