【问题标题】:PHP mail() BCC - display only the end receivers address in To: headerPHP mail() BCC - 仅在 To: header 中显示最终收件人地址
【发布时间】:2016-04-07 03:42:45
【问题描述】:

我正在尝试使用 PHP mail() 从数据库中密件抄送订阅者列表。一切正常,但我遇到了一个困扰我一上午的问题。我可以使用密件抄送发送列表,但无法将接收端电子邮件地址附加到更死的“收件人:”。

例如,我将列表发送到以下电子邮件地址(test1@example.com、test2@example.com 和 test3@example.com)。每个电子邮件地址都会收到一封电子邮件,而其他电子邮件地址由于密件抄送而被隐藏。

我的问题是,在标题中,“收件人:”在列表的所有接收端都显示为空白。我理解并知道该标头不会显示,因为我在传出消息中只有 BCC 标头。我已经尝试for 循环这个过程,但我收到了所有的电子邮件,加上一个循环中的地址。

这是我的工作代码:工作代码包括我尝试解决 To: 标头的循环。尽管我收到了所有已发送的电子邮件,但我可以发送电子邮件。

<?php

/*
   Gathers the number of rows within the database. Used for the loop that displays the entire list in the BCC. 
*/

   session_start();
   include_once '../dbconnect.php';
   $result = mysql_query("SELECT * FROM news");
   $num_rows = mysql_num_rows($result);
   $rows = $num_rows;

/*
   Requests the list from the database, please the list in a loop, displays the list only once, and places list in an operator.
*/

   $result = mysql_query("SELECT * FROM `news`");
     while($row = mysql_fetch_array( $result )) {
       for ($x = 1; $x <= 1; $x++) {
         $contacts.= "".$row['email'].",";
       }
     }

/*
   ATTEMPT (It works... sort of): Sends mail to the list using BCC, displays the ONLY receivers email address in the To: header
*/

   $result = mysql_query("SELECT * FROM `news`");
     while($row = mysql_fetch_array( $result )) {
       for ($x = 1; $x <= 1; $x++) {
         $receiver= "".$row['email']."";

         $to = "$receiver";
         $subject = 'Test Email';
         $headers = "From: example@example.com\r\n";
         $headers .= "BCC: $contacts";

         $headers .= "MIME-Version: 1.0\r\n";
         $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
         $message = '<html><body>';
         $message .= '<h1 style="">Test Message</h1>';
         $message .= '</body></html>';
         mail($to,$subject, $message, $headers);
      }
    }
?>

我的一般想法是循环,但我找不到真正完全解决这个问题的解决方案,由 BBC 到列表并在 To: 标题中仅显示接收端电子邮件地址。有什么想法或想法吗?

使用 SMTP 服务器更新

我一直在尝试使用此线程中的解决方案并将其应用于 SMTP 服务器。使用 SendGrid 发送消息是理想的选择。我提出了以下选项,但脚本似乎只向数据库中的一个地址发送一条消息,而不是所有地址。

<?php
require_once "Mail.php";

$sub = $_POST['subject'];
$ttl = $_POST['title'];
$img = $_POST['image'];
$bdy = $_POST['body'];
$lk = $_POST['link'];

mysql_connect("", "", "") or die(mysql_error()) ; 
   mysql_select_db("") or die(mysql_error()) ; 

  $result = mysql_query("SELECT `email` FROM news");

  $num_rows = mysql_num_rows($result);

  $receivers = array();
  while ($row = mysql_fetch_array($result)) {
    $receivers[] = $row['email'];
  }

  foreach ($receivers as $receiver) { }

$from = "test@example.com";
$to = $receiver;
$subject = $sub;
$mime = "1.0";
$ctype = "text/html; charset=ISO-8859-1";
$body = '
<html><body>
<p>Test Message!</p>
</body></html>
';

$host = "";
$port = "";
$username = "";
$password = "";

$headers = array ('From' => $from,
  'To' => $to,
  'Subject' => $subject,
  'MIME-Version' => $mime ,
  'Content-Type:' => $ctype);

$smtp = Mail::factory('smtp',
  array ('host' => $host,
    'port' => $port,
    'auth' => true,
    'username' => $username,
    'password' => $password));

$mail = $smtp->send($to, $headers, $body);

if (PEAR::isError($mail)) {
  echo("<p>" . $mail->getMessage() . "</p>");
} else {
  echo("<p>Message successfully sent!</p>");
}
?>

【问题讨论】:

  • 只通过“to”发送邮件怎么样?为什么 BCC 有这么多麻烦?您的服务器发出的邮件数量是否有限?
  • 不,我没有限制。我从列表中隐藏了地址,因为这是用于客户邮件列表的脚本。
  • 是的,我知道,但是,让我用代码快速回答一下我的实际意思;)
  • 啊,我明白了。谢谢!

标签: php email loops header


【解决方案1】:

\r\n 添加到:

$headers .= "BCC: $contacts\r\n";

每个标题都必须换行。

【讨论】:

  • 谢谢!现在正在尝试。我会告诉你它是否有效。
  • 这似乎可行,尽管它只发送一封电子邮件。我认为循环只是将一个地址附加到操作员。
  • 如果您想向所有电子邮件地址发送电子邮件,请删除 for 循环。
  • 如你所说,它只发送第一封电子邮件。
【解决方案2】:

该代码包含对您的代码的一些一般性改进。我添加了内联 cmets 来解释我做了什么。

<?php

  // General thing: If you do not need a session, do not start one ;)
  session_start();

  include_once '../dbconnect.php';

  // Select only what you really need from the table. This saves you memory
  // and it speeds up the query.
  $result = mysql_query("SELECT `email` FROM news");

  // You are not using these numbers in the script you showed us. I am just
  // leaving them in here to show you, how you can reuse the "$result"
  // variable without querying the database again.
  $num_rows = mysql_num_rows($result);

  // We are reusing the "$result" here without re-querying the database, which
  // speeds the whole process up and takes load away from the database. We are
  // storing all receivers in a dedicated variable, to reuse them later on.
  $receivers = array();
  while ($row = mysql_fetch_array($result)) {
    $receivers[] = $row['email'];
  }

  // Now, instead of querying the database again, we are using our stored mail
  // addresses in "$receivers" to send the emails one by one. We could have
  // done this part in the "while" loop before, but I wanted to stay close to
  // your code, so you would recognize it ;)
  foreach ($receivers as $receiver) {
    // I have removed the "for" loop here, because it runs only once. If a loop
    // only runs once and you control all its input, you really do not need a
    // loop at all (except some exceptions, just in case someone knows one^^).

    // You can actually just put the value of $receiver in $to. PHP is pretty
    // good at typecasting of scalar types (integers, strings etc.), so you do
    // not need to worry about that.
    $to = $receiver;

    $subject = 'Test Email';

    // I am putting the headers into an array and implode them later on. This
    // way we can make sure that we are not forgetting the new line characters
    // somewhere.
    $headers = array(
      "From: example@example.com",
      "MIME-Version: 1.0",
      "Content-Type: text/html; charset=ISO-8859-1",
      // I have removed the "BCC" header here, because this loops send out an
      // email to each user seperately. It is basically me sending an email to
      // you. Afterwards I copy&paste all the content to another new mail and
      // send it to another fella. You would never know that you both got the
      // same mail ;)
    );

    $message = '<html><body>';
    $message .= '<h1 style="">Test Message</h1>';
    $message .= '</body></html>';

    // Imploding the headers.
    $imploded_headers = implode("\r\n", $headers);

    mail($to, $subject, $message, $imploded_headers);
  }

此代码基本上一次发送一封电子邮件。收到此类电子邮件的人都不知道该电子邮件发往了哪些电子邮件地址。

代码中提到,这个sn-p可以进一步优化。由于电子邮件发送本身是一个相当困难的领域,我真的建议您找到一些 PHP 库来捆绑整个事情并使用它。在整个电子邮件发送过程中,您可能会犯很多错误,如果您不想很快被标记为垃圾邮件,我不会在生产环境中运行这样的脚本。

【讨论】:

  • 太棒了,你是最棒的。谢谢!好的,我会进一步寻找捆绑包。也许是 PHPMailer 或 SendGrid PHP?
  • 你应该阅读它们。你永远不会知道更少;P 只需找出哪一个更适合您的需求。您应该在决定时考虑他们的文档,因为您可能需要经常使用它们。
  • Okie dokie。是的,我不想被标记为垃圾邮件。再次,非常感谢您修改后的代码。帮了大忙!
  • 嘿@func0der 我听取了您的建议,将脚本打包并将其与系统捆绑在一起,以减少被标记为垃圾邮件的可能性。我在原始帖子中包含了我正在使用的脚本。它利用 PEAR 和 SMTP。我正在尝试使用 SendGrid 发送。它可以工作,但只发送一条消息和一个地址。关于如何重新建立该循环的任何想法?
  • 检查这一行:foreach ($receivers as $receiver) { }。如果不需要,请尽量避免在循环中构建类。您可以重复使用它们。在我的代码示例中查看我对$headers 的评论。你应该只在循环中为每个接收器生成真正改变的东西。
猜你喜欢
  • 2014-12-22
  • 2016-02-02
  • 2013-08-27
  • 2018-06-27
  • 2016-03-29
  • 1970-01-01
  • 2016-04-07
  • 2021-03-03
  • 2013-09-13
相关资源
最近更新 更多