电子邮件中foreach的问题

时间:2015-09-03 00:49:51

标签: php email loops for-loop foreach

我正在尝试创建一个电子邮件,发送给每个用户组5的用户。我希望电子邮件发送给该组中的每个用户...不确定我是否在这里这样做?

无论如何,电子邮件不会被发送。我得到一个关于我的foreach参数的错误,我查了一下,但无法弄清楚如何构造它。我想要它做的就是按照它们在表中的顺序来回显我的user_players表中的用户名。

任何帮助都将不胜感激。

$order_stmt= $con->prepare("SELECT * FROM users, user_players WHERE 'users.group'=5");
$order_stmt->execute() or
        die('Draft order email execute() failed: ' . htmlspecialchars($draft_stmt1->error));

    $order_row = $order_stmt->fetch();

    $order_id = $order_row['id'];
    $order_firstname = $order_row['firstname'];
    $order_lastname = $order_row['lastname'];
    $order_username = $order_row['username'];
    $order_email = $order_row['email'];
    $order_group = $order_row['group'];

    $to = $order_email;
    $subject = 'Draft Order';
    $message = '
    <html>
    <head>
        <title>Draft Order</title>
    </head>
    <body>
        <p>Hi '.$order_firstname.',</p><br>
        <p>The draft order has been created. This is a completely randomized selection.</p>
        <p>The draft order is of the following:</p><br>';
        foreach($order_row as $order) {
            echo $order_username;
        }
        $message .='<p>Thank you,</p>
        <p>Administration</p>
    </body>
    </html>
    ';

    $from = "user-requests@example.com";
    $Bcc = "user-requests-confirm@example.com";

    // To send HTML mail, the Content-type header must be set
    $headers  = 'MIME-Version: 1.0' . "\r\n";
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

    // Additional headers
    $headers .= 'To: ' .$to. "\r\n";
    $headers .= 'From: ' .$from. "\r\n";
    $headers .= 'Bcc: '.$Bcc. "\r\n";

    // Send the email
    mail($to,$subject,$message,$headers);
}

更新:

user_players
CREATE TABLE `user_players` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `user_id` int(11) NOT NULL,
 `firstname` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `lastname` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `username` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `email` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player1` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player2` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player3` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player4` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player5` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player6` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player7` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player8` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player9` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player10` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player11` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player12` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player13` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `player14` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=158 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci


    users
CREATE TABLE `users` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `firstname` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `lastname` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `email` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `phone_number` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
 `username` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `password` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
 `salt` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
 `joined` datetime NOT NULL,
 `group` int(11) NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=95 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

3 个答案:

答案 0 :(得分:0)

(删除了原来的答案,因为我的PHP生锈了。)

你有一个名为$ order_row的数组:

 foreach($order_row as $order) {
        echo $order[‘Field Name in Table’];
 }

此外,请参阅此帖:PHP SQL Foreach Statement

答案 1 :(得分:0)

嗯,很多问题,但让我们从主要问题开始:你的架构和你的SQL。

通过查看数据库转储,我不明白为什么表应该分开。除非您希望每user_playersusers超过users,否则模型是错误的。此外,如果您想组建一个playerX的“团队”(这就是team字段的内部数量的原因),我认为使用team表格会更好在usersSELECT * FROM users INNER JOIN user_players ON users.id=user_players.user_id WHERE users.group=5之间建立多对多关系(如果用户只能在一个团队中,则为一对多关系)。

我不想继续修复具有重大基础缺陷的东西,但如果你不能或不会改变你的数据库模型(也因为我喜欢一个很好的挑战),那么试试吧:{{ 1}}

execute or die()没用,因为据我所知,即使它返回一个空的结果集,它仍然有效!换句话说,die()仅在无法连接到数据库或其他类似异常时执行。同样or die()不是一个好习惯,如果你问if (!empty(order_row))并将其余代码封装在if中并将else显示错误,则效果会更好。 (这就是你的foreach失败的原因,它需要一个数组但是得到一个空或变量的空值。

<击> 现在,根据this

  

public mixed PDOStatement :: fetch ([ int $ fetch_style [,int   $ cursor_orientation = PDO :: FETCH_ORI_NEXT [,int $ cursor_offset = 0   ]]])

     

从与PDOStatement对象关联的结果集中获取一行。

     

fetch_style 控制下一行将如何返回给调用者。该值必须是PDO :: FETCH_ *常量之一,   默认值为PDO :: ATTR_DEFAULT_FETCH_MODE(默认为   PDO :: FETCH_BOTH)。

     

PDO :: FETCH_BOTH(默认值):返回由两列索引的数组   结果集中返回的名称和0索引列号。

这意味着$order_row = $order_stmt->fetch();同时返回关联和单行的编号数组(稍后这将很重要),换句话说,将重复每一个值

//PDO::FETCH_BOTH: Return next row as an array indexed by both column name and number.
Array (
    [name] => banana
    [0] => banana
    [colour] => yellow
    [1] => yellow
)

将其更改为:$order_row = $order_stmt->fetch(PDO::FETCH_ASSOC);只有一个关联数组,字段名称为关键字。问题是由于SQL的INNER JOIN,重复的字段(id,用户名,名字,姓氏,电子邮件)只会显示一次而且只显示“左”部分(users)。

修改

抱歉,我误以为您使用prepareexecute作为PDO,事情是,mysqli如果您看到here,那么您错过了一个非常重要的步骤,你会发现这个宝石:

  

将准备好的语句中的结果提取到 mysqli_stmt_bind_result()绑定的变量中。

Return Values 
Value   Description 
TRUE    Success. Data has been fetched
FALSE   Error occurred 
NULL    No more rows/data exists or data truncation occurred

这意味着,每个结果只有1的原因是因为fetch每次成功获取都会返回TRUE(相当于1),你说你有3条记录,做数学。但是如果你使用this,那么你必须知道每一列及其顺序,以便将值设置为变量,让我们这样做:

$order_stmt->execute();
$order_result = $order_stmt->get_result();
$order_row = $order_result->fetch_array(MYSQLI_NUM)

END_EDIT

但阅读您的评论只需要playerX数据,现在我们有一个关联数组,对filter执行regex of the key

$players = array_filter(function($key){
    return preg_match('/^player',$key) === 1;
},$order_row,ARRAY_FILTER_USE_KEY);

现在我们有一个只包含播放器的数组,我们可以randomize它(就像你在邮件中所说的那样)并做一个正确的foreach

但在此之前看一下这个简化的代码:

$message = "I'm saving text in a variable";
foreach ($array as $value){
    echo "i'm echoing a $value";
}
$message .= "I'm concatenating in the same variable as before!";

看到错误?如果您希望将foreach echo数据放入邮件中,则这是完全错误的。因为echo在浏览器中输出给用户....换句话说,foreach甚至不知道$message存在!

请改为:

$random_keys = array_rand($players, 5) //here we get our 5 lucky victims
$message = " Put here the same part of the email but do this at the end:<br>
    <ul>";
foreach ($random_keys as $key){ //so you only iterate 5 times
    $message .= "<li>I'm putting every {$players[$key]} in a nice list</li><br>";
}
$message .= "</ul>
    put here the last part of the email.";

完成!,现在你发送电子邮件......等等,什么!您还需要为小组中的每个人重复此电子邮件吗?

EASY!

还记得我说过要记住一些东西吗?

  

这意味着$order_row = $order_stmt->fetch();同时返回关联和单行的编号数组稍后会很重要

所有你需要做的就是把我之前提到的if(你检查结果行是否为空的那个)放在while里面,这个while($order_row = $order_stmt->fetch(PDO::FETCH_ASSOC)){ 循环遍历每个结果集在小组中:

<击>

<击>
while ($row = $result->fetch_array(MYSQLI_NUM)){
    if(!empty($order_row)){
        // assign the variables, format the message and send the email...
    } else {
        echo 'The query is bad and i should feel bad or the database has no records for this group';
    }
}

<击>

{{1}}

答案 2 :(得分:0)

尝试将$order_row = $order_stmt->fetch();更改为$order_row = $order_stmt->fetch_assoc();

然后在您的foreach循环中,将echo $order_username;更改为echo $order['username'];