电子邮件中的foreach循环出现问题

问题描述:

我在生成电子邮件时无法正确使用foreach循环来正常工作。我搜索了答案,并且找到了将foreach循环插入到电子邮件的说明,但没有任何有关循环无法正常工作的信息。电子邮件中的foreach循环出现问题

我试图在下单后将订单收据通过电子邮件发送给客户,并且电子邮件中的所有内容都将交付,但物品清单除外。

我会尝试尽可能多地包含我的逻辑: 订购时,购物车物品的数组将被序列化,然后存储在数据库中。付款处理程序返回支付成功后,我会在用户可以打印的网站上显示收据页面。订单项目是从数据库中检索如下:

$stmt = $dbh->prepare("SELECT * FROM *table* WHERE orderID = :q0") 
$stmt->bindValue(":q0",$orderNum) 
$stmt->execute(); 
foreach($stmt as $row) { 
    $items = unserialize($row['order_contents']); 
} 

在这一点上,如果我回声$项目,我看到的顺序选择项目的数组。到现在为止还挺好。

现在,因为我正在使用PDO,查询中的foreach循环并不是我已经想出的方法。相反,我已经初始化一个变量来保存从foreach循环的项目:

foreach($items as $prod_id => $value) { 
    $q .= $prod_id . ','; 
} 
$q = substr($q, 0, -1); 

这存储在一个变量数组,我现在可以在PDO语句中使用了一个查询:

$stmt2 = $dbh->prepare("SELECT * FROM *productTable* WHERE prod_ID IN ($q)"); 
$stmt2->execute(); 
foreach($stmt2 as $row) { 
$itemName = htmlentities(strip_tags($row['prod_name'])); 
$id = htmlentities(strip_tags($row['prod_ID'])); 
$qty = htmlentities(strip_tags($items[$prod_id]['quantity'])); 
$price = $items[$prod_id]['price']; 
echo " 
    <tr> 
     <td>".$qty."</td> 
     <td>".$itemName."</a></td> 
     <td>".$price."</td>       
    </tr>"; 
} // THIS CODE WORKS. I can see each item from the order as a new row in the table 

再次,迄今如此好。我可以运行一个foreach循环来将这些项目回显到页面中,并且它们都会显示适当的项目名称以及我从此示例中遗漏的表格中的其他信息。

跳到文件的末尾,我有下面的脚本不起作用,我不明白为什么。电子邮件发送成功,但没有任何来自foreach循环的产品出现在电子邮件中。

$to = '[email protected]' 
$subject = 'Your order receipt for order '.$orderNum 
$headers = 'From: [email protected]'."\r\n". 
      'Reply-To: [email protected]'."\r\n". 
      'Content-Type: text/html; charset=UTF-8'."\r\n". 
      'X-Mailer: PHP/'.phpversion(); 
$message = '<html><body>'; 
$message .= '<h2>Thanks for your purchase!</h2><br>'; 
$message .= '<p>Here are the details of your order number '.$orderRef.':<br><table>'; 
$message .= ' 
<tr style="width: 100%;"> 
    <th scope="col" style="width: 20%;">Quantity:</th> 
    <th scope="col" style="width: 60%;">Name:</th> 
    <th scope="col" style="width: 20%;">Price:</th> 
</tr> 
'; 
foreach ($stmt2 as $row) { 
    $message .= " 
    <tr> 
     <td>".$qty."</td> 
     <td>".$itemName."</td> 
     <td>".$price."</td>       
    </tr>"; //THIS CODE DOESN'T WORK, Even though it's using the same variables as the loop from above. 
} 
$message .= '</table><br>'; 
$message .= 'If you have any questions about your order, please call us at <b>XXX-XXX-XXXX</b>'; 
$message .= '</body></html>'; 
mail($to, $subject, $message, $headers); 

电子邮件发送,我看到foreach循环之前和之后的一切,但我没看到实际项目正在生成。在电子邮件代码之后,我可以将变量回显到页面,并且它们都可以正确显示,因此变量仍然被声明。

可能相关或不相关的其他信息: 我试图在Ubuntu 14.04上使用新映像的VPS执行此代码。 我刚刚在星期一安装了SSL证书 我最近在我的VPS上安装了UFW。 SMTP,IMAP和UTP端口不会被阻止。 PHP版本5.5.9-1ubuntu4.21

这里的电子邮件输出的截图:screen capture of email

编辑: 变量的第一的foreach(如$行stmt2 $)语句后已经被定义。我已经添加了额外的代码来反映这一点。

$stmt2不是一个数组,它是一个生成器。除此之外,它只允许根据需要将行加载到内存中,而不需要一次将整个内容读入内存。

抓的是,你不能foreach它两次。您需要将其转换为实际的数组。我还没有测试过,但是你可以用$itemdata = iterator_to_array($stmt2)做到这一点 - 如果在你的第一个foreach里面只有$itemdata[] = $row,那么你可以稍后参考这个$itemdata数组。

+0

无法对结果进行两次foreach是不是我所知道的。我将SQL语句复制到电子邮件区域,现在它完美地工作。感谢您的帮助。 – Mark

+0

@马克是的,它可能是一个陷阱。当'mysql_ *'函数是一件事情时,我学会了它,并且无法解决为什么我不能在结果集上多次'XD'现在,当然,我使用一个包装类,我们的设计是为了支持重新设置。 –

我认为问题出在foreach循环中。

foreach ($stmt2 as $row) { 
    $message .= " 
    <tr> 
     <td>".$qty."</td> // $qty is undefined! You should use $row['qty'] or $row->qty 
     <td>".$itemName."</td> // $itemName is not defined 
     <td>".$price."</td> // $price is not defined 
    </tr>"; 
} 

我希望它有帮助。

+0

我已经编辑了这个问题,我忘了在里面添加变量。已经宣布,但感谢您注意到我的错误。不幸的是,我不认为foreach循环是问题,但RiggsFolly提出了一个关于获取(PDO :: FETCH_ASSOC)的好处 - 我不相信我没有想到要使用它。 – Mark

我结束了再次加入SQL查询,电子邮件码内的解决方案:

$message .= '<p>Here are the details of your order number '.$orderRef.':<br> 
<table>'; 
$message .= ' 
<tr style="width: 100%;"> 
    <th scope="col" style="width: 20%;">Quantity:</th> 
    <th scope="col" style="width: 60%;">Name:</th> 
    <th scope="col" style="width: 20%;">Price:</th> 
</tr> 
'; 
$stmt2 = $dbh->prepare(" 
SELECT * FROM products WHERE prod_ID IN ($q) ORDER BY prod_id ASC 
"); 
$stmt2->execute(); 
while ($row = $stmt2->fetch(PDO::FETCH_ASSOC)) { 
    $itemName = htmlentities(strip_tags($row['prod_name'])); 
    $id = htmlentities(strip_tags($row['prod_ID'])); 
    $qty = htmlentities(strip_tags($items[$prod_id]['quantity'])); 
    $price = $items[$prod_id]['price']; 

    $message .= " 
    <tr> 
     <td>".$qty."</td> 
     <td>".$itemName."</td> 
     <td>".$price."</td>       
    </tr>"; 
    } 
$message .= '</table><br>'; 

,然后将其余的代码。它似乎现在工作,我的测试电子邮件显示测试订单中的两个项目。

谢谢大家的建议。