Adding CC Recipients With PEAR Mail

I use the PEAR Mail package quite often in projects that require sending email -- either user-generated or system-level notification emails. I recently wrote something at work that required CCing the user a copy of the email. My first thought was that simply adding CC headers with the users' email address would suffice, but that just isn't the case.

Since mail headers can be modified to state anything you want, PEAR Mail doesn't actually use them to to figure out where to send the email (adding the CC header works fine and the users' email address even shows up in the CC field, but they never receive the email).

A comment by Armin Frey that I found on the PEAR bug page for this problem explains what's going on and offers a solution:

[2007-07-06 15:22 UTC] arminf (Armin Frey)

It seems that the Recipients decides where to send the e-mail and the
headers decide how to display it.

The simple solution is that you add all the addresses to $recipients.

Here is the code I used:

$to = '[email protected]';
$cc = '[email protected]';
$recipients = $to.", ".$cc;
$headers['From']    = '[email protected]';
$headers['To']      = $to;
$headers['Subject'] = 'Test message';
$headers['Cc']	    = '[email protected]';
$headers['Reply-To'] = '[email protected]';

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

The solution works perfectly. Now the email addresses show up in the correct fields and all the recipients receive the email. Unfortunately, this method does not work for BCCing users. I wonder if BCCing is even possible with PEAR Mail or if I'll need to find something else. To Blind CC (aka, BCC) an address, simply add the address to the $recipients, but not to any of the $headers (thanks Jason!).

Write a Comment



  1. For anyone you want to BCC, concat the email addresses into the $recipients string. You don’t have to add them anywhere else. As you said, the headers display whatever you want, and recipients actually sends the mail. There’s no need to print the BCC in the header because nobody sees it (blind carbon copy). Email will get sent to all email addresses in $recipients regerdless of how the header displays them.

  2. This doesn’t seem to work for me. I’ve copied and pasted your script and only changed the addresses. Everything that goes into $recipients appears in the to: line of my email program. $headers works fine and I can add or withhold information there but no matter what I do I still show everything in the $recipients variable.
    Any thoughts?

  3. You’re sure you added the $headers['Cc']? Normally what the email client displays is determined by the headers in the email. Try doing “view source” from your email client to see what the headers of the email look like.

  4. Thanks Raam.
    Yes I’ve checked everything so many times but I must be missing something obvious. I echoed the strings after sending and they look OK but as you suggested I checked the message source and all addresses appear in the “To:” This is the same in Yahoo and Thunderbird.
    One fault I did find was that I didn’t use a capital T in the $headers[‘To’]. That caused the “To” address to be appended to the end of $recipient again but since then I only receive the message once (Sent and Cc’d to myself so should get 2).
    Here is a portion of my script.

    $to=’[email protected]’;
    $cc=’[email protected]’;
    $addresses=’[email protected], [email protected], [email protected]‘;

    $recipients = $to.’, ‘.$cc.’, ‘.$addresses;
    $headers[‘From’] = $from;
    $headers[‘To’] = $to;
    $headers[‘Subject’] = $subject;
    $headers[‘Cc’] = $cc;

    $mail = Mail::factory(“mail”);
    $send = $mail->send($recipients, $headers, $body);

    echo(“To: $to”);
    echo(“Recipients: $recipients”);
    echo(“Cc: $cc”);
    The echo at the bottom was for me to check what was being sent from my form. The $from is generated earlier in the form.
    Can you see what I’m doing wrong?


  5. Hey John,

    Everything looks correct. You might want to try echoing the individual headers to make sure they contain what you’re expecting (e.g., echo headers['Cc'];).

    The only other thing I can think of is that somehow the headers are being striped or changed by the mail server that you’re using to send email. If you’re setting the headers properly but the email arrives with something different, then something is happening between the PHP code and the email being received by the recipient server.

    I just checked some of my own code, and I’m using it exactly like my example above and the emails sent out are received with the email address in the proper Cc header.

    Also, it appears that the correct syntax for the Cc header is “Cc“, but you might want to try changing it to “CC or cc” just for kicks.

    Just to make sure I’ve got this right, the email address(es) in the Cc field are received by the recipient, but they appear in the To field instead of the Cc field, correct? What version of PEAR::Mail are you using?

  6. Thanks Raam
    It looks like version 1.1.14 that is installed on the server.
    The Cc is not a problem, I can live with that but it is the addresses I don’t want to show (Bcc) which appear in the To: header when the email arrives at a destination.
    The outgoing string from my form looks as it should;-
    Cc: [email protected]
    Header to: [email protected]
    Header Cc: [email protected]
    I guess I’ll just have to keep playing with it or maybe contact the server support.
    Thanks for your advice.

  7. John,

    I mentioned at the end of this post that I was also unable to get BCC working: “Unfortunately, this method does not work for BCCing users. I wonder if BCCing is even possible with PEAR Mail or if I鈥檒l need to find something else.”

    None of your examples had any BCC headers so I didn’t catch onto the fact that you were trying to do that. :-p

    If you find a solution, I would love to hear about it. I can’t even count how many hours I spent trying to get BCC working!

  8. I don’t agree that it is a nuisance, only the fact that I can’t get it to work. I need to mail to around 150 people and some do not want their email addresses to be disclosed, hence the Bcc. being easier than sending 150 individual emails.
    Ramm, I had spotted your posting but I assumed that, after Jason wrote, you must have got it to work. Thanks for your help and if I do find a solution I will post it.


  9. I have found that using a separate service like Constant Contact makes things so much easier. Whenever you send email to large numbers of people like that you risk being thought of as a spammer by email servers.

    I admit that I haven’t written any PHP stuff that sends out mass-emails (mainly because I recognized how much trouble it would be), but I can understand how some situations might require a custom script. One thing I found that makes my life a lot easier is having a separate SMTP service to deliver my email.

    I use AuthSMTP and they’re great. As long as you keep within their stated limits, you’ll be OK and won’t have to worry about being accidentally thought of as a spammer.

  10. Looks like you may be confusing CC and BCC. CC WILL be visible in the header. If you want to BLIND CC, just take out

    $headers[‘Cc’] = $cc;

    and leave the recipients as is. That’s it.

    Here’s my use case if this helps anyone, and I believe justifies a use for BCC. I use the BCC feature for my ordering feature, but not for mass email. When a user submits an order, PEAR kicks off an email receipt to them, and BCCs the sales dept. It’s good so the admin knows the instant an order is submitted. Also, If for some reason the user says they didn’t receive the receipt, or complain of a discrepancy in the text of the receipt, then we have an actual copy of the email that was sent to them, with their email address in the TO field. Keeps everybody honest and helps big time if any customer service issues pop up.

    For mass email, like kicking out newsletters, I just use Outlook since I only need to do it intermittently. I COULD write code to do it, but it’s not worth the effort for how seldom I need to send stuff out in bulk. And with code, it wouldn’t be any easier than using outlook to send stuff out anyway.

  11. Thanks Jason!

    I just tried adding an email address to $recipients, but not to any of the headers, and it worked (the user was BCC’ed)!

    I’ll update my post with this explanation.

    Edit: I just realized you’re probably the same Jason that first commented on this post and said BCC will works. I don’t know why I didn’t just update the post then! Doh!

  12. The Send() method of the Pear mail package takes an array of values thus:

    $recipients[“To”] = ‘[email protected]’;
    $recipients[“Bcc”] = ‘[email protected]’;
    $recipients[“Cc”] = ‘[email protected]’;

    $header[“From”] = ‘[email protected]’;
    $header[“To”] = ‘[email protected]’;
    $header[“Subject”] = ‘Subject’;

    $body = ‘Hello world!’;

    $smtpinfo[“host”] = “”;
    $smtpinfo[“port”] = “25”;
    $smtpinfo[“auth”] = true;
    $smtpinfo[“username”] = “username”;
    $smtpinfo[“password”] = “password”;

    $smtp = Mail::factory(‘smtp’, $smtpinfo);

    $mail = $smtp->send($recipients, $header, $body);

    What’s important to note is that the header needs to contain a “To” address, “From” address and a “Subject”. “Cc” or “Bcc” in the header is not required and in fact in the case of “Bcc” is pointless since you’d be giving away who you send the email to in the header information when that is not what you want (or you’d just use “Cc” presumably).


    And yes, it’s poorly documented.

  13. I’m using one To address and lots of “Bcc”. Only issue is that randomly one of the email addresses is shown in the email headers! Here’s an example (I’ve commented out private info).

    Received: from **IP-ADDRESS** ([**IPADDRESS**]) by
    **DOMAIN** with emfmta (version **NUMBER**) vanilla id

    If I send another email a different Bcc address is used. Any ideas?


  14. Same as above, but with my addresses. I spoke to my email host and they think it may be an issue with their server; they are working on it.

  15. Many thanks for this excellent post. I’ve been tearing my hair out trying to find a solution to the PEAR Mail Bcc problem. (Problem, what problem?)

  16. For anyone who stumbles upon this after so long after it was made, the workflow makes a lot more sense when you know about smtp, take this example using putty (when you look at an email sent through like this, you get to understand it more and more):

    220 ************.com ESMTP Postfix
    helo ************.com
    250 ************.com
    mail from: /* This is who the message is  from*/
    250 2.1.0 Ok
    rcpt to: // This is whom the message is intended//
    250 2.1.5 Ok
    data  /* initialising the main data (this includes all the displayed data (subject, to address, from address, cc's etc..))*/
    354 End data with .
    subject: hello /*the displayed subject*/
    from: nick /*the from address this completes as nick@([address given at the start].com)*/
    /*this new line indicates the message starts and headers end*/
    hello this is a test
    /*. (this indicates the end of the message(not inputting the actual characters, these are Carriage returns and line feeds (confused me at first XD))) */
    250 2.0.0 Ok: queued as 554561217AF
    now when you look at the message:
    == header ==
    from:	 nick@************.com
    reply-to:	 nick@************.com,
    to:	         /* if you notice above, there is no to: address specified...*/
    date:	 Wed, Nov 20, 2013 at 11:56 AM
    subject:	 hello
    == The message content ==
    hello this is a test
    ### from here it is info about the actual mail function ###
    require_once "/usr/share/pear/Mail.php"; /*default install locations on my EC2 instance*/
    require_once "/usr/share/pear/Mail/mime.php";
    $from = "no-reply ";
    $subject = "This is a test";
    $crlf = "rn";
    $html = "This is a test, hi all!";
    $from = "someone ";
    $to   = "nick "; /*this is the address that will be displayed in the to: header*/
    $totwo= "steve "; /*this is the BCc we don't want this in the headers ;) */
    $headers = array('From' => $from, /*if we were in putty this would be From: [from address]*/
    		'To' => $to,  /*if we were in putty this would be To: [To address]*/
    		'Subject' => $subject); /*if we were in putty this would be subject: [your subject]*/
    //$host = "";
    $host = "ssl://"; // try this one to use ssl
    $port = 465;
    $username = "clientrepository@************.com"; /* email address of google account*/
    $password = "************";  /* password of that account*/
    //$mime = new Mail_mime($crlf);
    $mime =  new Mail_mime(array('eol' => $crlf)); /* i believe this is where we separate the header and message info[but don't take my word on it XD] this is based on the pear doc*/
    //$body = $mime->get();
    $body = $mime->getMessageBody(); //based on pear doc above
    $headers = $mime->headers($headers);
    $smtp = Mail::factory("smtp",array("host" => $host,
    		"port" => $port,
    		"auth" => true,
    		"username" => $username,
    		"password" => $password));
    $sendto = array($to, $totwo); /* can be either a single value or an array,  an array is the better option as then you could just use an array to input the to values ;)  */
    $mail = $smtp->send($sendto, $headers, $body);
    if (PEAR::isError($mail)) {
    	echo $mail->getMessage();
    } else {
    	echo "Message sent successfully!";
    echo "n";

    I was recently taught this so may be a couple of errors in my explanation, in terms of BCc, the idea is you don’t put in header information, that why when you try and put in the headers field

    Bcc => email

    it wont work, I hope this helps someone 馃檪



  17. I tried this and it works, but……….. then I got
    “undisclosed-recipients” !!!!!
    My solution for Cc with php PEAR -> to send a seperate email to the Cc recipient.
    I hope somebody finds a better solution!

  18. Thank you!

    I was struggling getting CC and BCC to work with PEAR mail with some existing forms. Your post got me going on the right path to a solution and all is working again.