在循环期间移动到搜索数组的下一行,但在列更改时中断


Moving to the next row of a search array during a loop, but breaking when a column changes

我正在循环通过MySQL表的数据和构建一个HTML表(在php中),将在这个表中显示名称,而一个特定的列或列保持不变。一旦这些列发生变化,那么我需要跳出内部循环,迭代到SQL表的下一行,然后在列保持不变的情况下再次启动内部循环。

 JobId  |        email        |  FName  |  LName  |  apply
   1    |   email1@gmail.com  |   Joe   |  Smith  |   1
   1    |   email1@gmail.com  |   Kim   | Joseph  |   1
   1    |   email1@gmail.com  |  Chris  |   Bell  |   1
   2    |   email2@gmail.com  |   Ben   |   Ken   |   0
   2    |   email2@gmail.com  |   Sam   |  Socks  |   1
   3    |   email3@gmail.com  |   Tom   |  Allen  |   0

根据上面的表格,我想要做的是能够向email1@gmail.com发送一封包含Joe, Kim和Chris名字的电子邮件。然后向下迭代,向email2@gmail.com发送第二封电子邮件,消息中包含Ben和Sam的名字,然后向email3@gmail.com发送第三封电子邮件,消息正文中包含Tom的名字。

我已经写了如何发送电子邮件等代码。我遇到的麻烦是正确地通过查询迭代。所以我把结果反馈到一个网页上,以帮助我解决这个问题,这样我就不会发送上千封电子邮件了。以下是我到目前为止的工作:

while($row = mysqli_fetch_array($result)){
    echo 'Applicants: <br />';
        $JobId = $row['JobId'];
    echo $row['FName'] . ' ' . $row['LNname'] . '<br />';
    while (mysqli_fetch_array($result)['JobId'] == $JobId){
        echo $row['FName'] . ' ' . $row['LName'] . '<br />';
    }
    echo 'email address: ' . $row['email'] . '<br /><br />';
}

这个遍历并只给我一次正确的电子邮件地址,这很好。但是,它每次迭代时都给我相同的FName和LName。我知道为什么($row数组不会迭代到查询中的下一行)。这就是我缺少的部分。

我也认为它显示名字的次数是不正确的…虽然不是很重要,但如果你能马上明白为什么,那也会很有帮助。

任何帮助都会很感激。谢谢!

我认为这应该工作:你只需要检查当前的JobId是否与以前不同,并保留最近的电子邮件地址的记录(这里在临时变量$email中)。警告:我还没有测试过这个!

$JobId = 0;
echo 'Applicants: <br />';
while($row = mysqli_fetch_array($result)){
    if ($row['JobId'] == $JobId) {
        // Nothing changed so save the email & carry on printing out names.
        $email = $row['email'];
        echo $row['FName'] . ' ' . $row['LNname'] . '<br />';
    } else {
        // We have a new JobId, so send the email, set the JobId marker,
        // and print the "Applicants" header again.
        echo 'Sending email to '.$email;
        $JobId = $row['JobId'];
        echo 'Applicants: <br />';
    }
}

嵌套while循环在这里没有意义,因为只有一个结果集要循环。如果内存使用不是主要问题,我建议构建一个多维数组来简化工作,将电子邮件作为第一个维度。像这样:

// build array
$email_array = array();
while($row = mysqli_fetch_array($result)) {
    $email_array[$row['email']][] = $row;
}
// loop array
foreach($email_array as $email => $row) {
    // $email contains the target email address
    // $row contains array holding JobId, FName, Lname, apply
    // build your email here with some logic
    // send your email to $email
    // iterate loop to get to next email address
}

@GluePear给了我一些很好的信息,我能够测试它,然后解决其余的问题。GluePear的代码基本上满足了我的要求,但由于某种原因,它缺少了每个分组的第一个名称。所以我做了一些工作,意识到这是因为当它到达else语句时,数组已经在下一行了,但是我们没有打印名字。所以我只是在那里添加了一个带有申请人姓名的echo和一个初始化的If语句,瞧!代码如下:

$first = 1;
echo 'Applicants: <br />';
//start while loop to go through data
    while($row = mysqli_fetch_array($result)){
      if($first == 1){                
        $email = $row['email'];   //set the email address
        echo $row['FName'] . ' ' . $row['LName'] . '<br />';        //output the name
        $JobId = $row['JobIid'];     //set the JobId to the current row's job id
        $first = 0;                 //change the first row so that we don't go through this initial if
} 
      else if ($row['JobId'] == $JobId) {
        $email = $row['email'];
        echo $row['FName'] . ' ' . $row['LName'] . '<br />';
} 
      else {
        //We have a new JobId, so send the email, set the JobId marker,
        // and print the applicants header again as well as the name of the next applicant from the current row
        echo 'Sending email to ' . $email . '<br /><br />';
        $JobId = $row['JobId'];
        echo 'Applicants: <br />';
        echo $row['FName'] . ' ' . $row['LName'] . '<br />';
  }
}
echo 'Sending email to ' . $email . '<br /><br />';

这是我发现的最好的方法。谢谢你的帮助。如果有人发现任何明显的错误,请告诉我。:)