71
votes

I can't seem to successfully send to multiple addresses when using Laravel's Mail::send() callback, the code does however work when I only specify one recipient.

I've tried chaining:

// for example
$emails = array("[email protected]", "[email protected]");
$input = Input::all();

Mail::send('emails.admin-company', array('body' => Input::get('email_body')), 
function($message) use ($emails, $input) {
    $message
    ->from('[email protected]', 'Administrator')
    ->subject('Admin Subject');

        foreach ($emails as $email) {
            $message->to($email);
        }
});

and passing an array:

// for example
$emails = array("[email protected]", "[email protected]");
$input = Input::all();

Mail::send('emails.admin-company', array('body' => Input::get('email_body')), 
    function($message) use ($emails, $input) {
        $message
        ->from('[email protected]', 'Administrator')
        ->subject('Admin Subject');

        $message->to($emails);
});

but neither seem to work and I get failure messages when returning Mail::failures(), a var_dump() of Mail::failures() shows the email addresses that I tried to send to, for example:

array(2) {
  [0]=>
  string(18) "[email protected]"
  [1]=>
  string(18) "[email protected]"
}

Clearly doing something wrong, would appreciate any help as I'm not understanding the API either: http://laravel.com/api/4.2/Illuminate/Mail/Message.html#method_to

I realise I could put the Mail::send() method in a for/foreach loop and Mail::send() for each email address, but this doesn't appear to me to be the optimal solution, I was hoping I would also be able to ->bcc() to all addresses once everything was working so the recipients wouldn't see who else the mail is being sent to.

11
Show more code. Have you tried to insert there existing emails. What failure messages you get?Marcin Nabiałek
What do you mean by existing emails? I am sending it to valid email addresses if that's what you mean? Will add more code with the failure messages. Thanks.haakym

11 Answers

118
votes

I've tested it using the following code:

$emails = ['[email protected]', '[email protected]','[email protected]'];

Mail::send('emails.welcome', [], function($message) use ($emails)
{    
    $message->to($emails)->subject('This is test e-mail');    
});
var_dump( Mail:: failures());
exit;

Result - empty array for failures.

But of course you need to configure your app/config/mail.php properly. So first make sure you can send e-mail just to one user and then test your code with many users.

Moreover using this simple code none of my e-mails were delivered to free mail accounts, I got only emails to inboxes that I have on my paid hosting accounts, so probably they were caught by some filters (it's maybe simple topic/content issue but I mentioned it just in case you haven't received some of e-mails) .

29
votes

If you want to send emails simultaneously to all the admins, you can do something like this:

In your .env file add all the emails as comma separated values:

[email protected],[email protected],[email protected]

so when you going to send the email just do this (yes! the 'to' method of message builder instance accepts an array):

So,

$to = explode(',', env('ADMIN_EMAILS'));

and...

$message->to($to);

will now send the mail to all the admins.

13
votes

the accepted answer does not work any longer with laravel 5.3 because mailable tries to access ->email and results in

ErrorException in Mailable.php line 376: Trying to get property of non-object

a working code for laravel 5.3 is this:

$users_temp = explode(',', '[email protected],[email protected]');
    $users = [];
    foreach($users_temp as $key => $ut){
      $ua = [];
      $ua['email'] = $ut;
      $ua['name'] = 'test';
      $users[$key] = (object)$ua;
    }
 Mail::to($users)->send(new OrderAdminSendInvoice($o));
9
votes

With Laravel 5.6, if you want pass multiple emails with names, you need to pass array of associative arrays. Example pushing multiple recipients into the $to array:

$to[] = array('email' => $email, 'name' => $name);

Fixed two recipients:

$to = [['email' => '[email protected]', 'name' => 'User One'], 
       ['email' => '[email protected]', 'name' => 'User Two']];

The 'name' key is not mandatory. You can set it to 'name' => NULL or do not add to the associative array, then only 'email' will be used.

5
votes

In a scenario where you intend to push a single email to different recipients at one instance (i.e CC multiple email addresses), the solution below works fine with Laravel 5.4 and above.

Mail::to('[email protected]')
    ->cc(['[email protected]','[email protected]','[email protected]','[email protected]'])
    ->send(new document());

where document is any class that further customizes your email.

2
votes

You can loop over recipientce like:

foreach (['[email protected]', '[email protected]'] as $recipient) {
    Mail::to($recipient)->send(new OrderShipped($order));
}

See documentation here

0
votes

This works great - i have access to the request object and the email array

        $emails = ['[email protected]', '[email protected]'];
        Mail::send('emails.lead', ['name' => $name, 'email' => $email, 'phone' => $phone], function ($message) use ($request, $emails)
        {
            $message->from('[email protected]', 'Joe Smoe');
//            $message->to( $request->input('email') );
            $message->to( $emails);
            //Add a subject
            $message->subject("New Email From Your site");
        });
0
votes

I am using Laravel 5.6 and the Notifications Facade.

If I set a variable with comma separating the e-mails and try to send it, I get the error: "Address in mail given does not comply with RFC 2822, 3.6.2"

So, to solve the problem, I got the solution idea from @Toskan, coding the following.

        // Get data from Database
        $contacts = Contacts::select('email')
            ->get();

        // Create an array element
        $contactList = [];
        $i=0;

        // Fill the array element
        foreach($contacts as $contact){
            $contactList[$i] = $contact->email;
            $i++;
        }

        .
        .
        .

        \Mail::send('emails.template', ['templateTitle'=>$templateTitle, 'templateMessage'=>$templateMessage, 'templateSalutation'=>$templateSalutation, 'templateCopyright'=>$templateCopyright], function($message) use($emailReply, $nameReply, $contactList) {
                $message->from('[email protected]', 'Some Company Name')
                        ->replyTo($emailReply, $nameReply)
                        ->bcc($contactList, 'Contact List')
                        ->subject("Subject title");
            });

It worked for me to send to one or many recipients. 😉

0
votes

Try this:

$toemail = explode(',', str_replace(' ', '', $request->toemail));
0
votes

This is what I am doing in one of my multi-vendor e-commerce projects.

$vendorEmails[0]    =    '[email protected]';
    foreach ($this->order->products as $orderProduct){
        $vendorEmails[$count] = \App\User::find($orderProduct->user_id)->email;
        $count++;
    }

    return $this->from('[email protected]', 'Made In India')
        ->to($this->order->billing_email, $this->order->billing_first_name . ' ' . $this->order->billing_last_name)
        ->bcc('[email protected]')
        ->cc($vendorEmails)
        ->subject('Order Placed Successfully - Made In India - ' . $this->order->generated_order_id)
        ->markdown('emails.orderplaced');
}
-12
votes

it works for me fine, if you a have string, then simply explode it first.

$emails = array();

Mail::send('emails.maintenance',$mail_params, function($message) use ($emails) {
    foreach ($emails as $email) {
        $message->to($email);
    }

    $message->subject('My Email');
});