Laravel and PHPMailer, Send Email from Localhost with Gmail SMTP
scriptwriterph technical support - free consultation

Laravel and PHPMailer, Send Email from Localhost with Gmail SMTP

Last updated on February 20th, 2021

Here we are having another client request -- to add email functionality in their Laravel app -- hosted on their localhost server. They want a contact form that'll be capable of sending email with CC (carbon copy) and BCC (blind carbon copy). They also requested an add file attachment feature in case they need to attach file/s to their email. They don't have any mail server setup on their local machine.

One of the library we can think of (that can do the job) is PHPMAiler. Well, why not right? PHPMailer is 20 years in business, supporting projects, making their library publicly available for anyone. Additionally, integration between Laravel and PHPMailer isn't new at all.

If you haven't tried PHPMailer yet (maybe you're using Laravel's Swiftmailer, Zend/Mail, ZetaComponents etc.), here's a quick background. In a nutshell, PHPMailer is a PHP library for sending email, simply as that, nothing complicated. Client requests we've stated above such as sending email with CC, BCC, and add file attachments supports by this library. Most importantly, it'll allow us to send email from a localhost server (even in Windows platform), through the use of Gmail SMTP of course. We can't list all features of this library here but you can read more about PHPMailer from this page.

Before we begin, let's take a look on what will be our output at the end of this tutorial.

Laravel form that sends email with CC, BCC and attachments from localhost Windows through the use of PHPMailer with Gmail SMTP

A simple contact form in Laravel that sends email with CC, BCC and attachments from a localhost server (Windows 10 specifically) through the use of PHPMailer with Gmail SMTP.

Requirements

  • Composer - we'll use this dependency management in PHP to easily install Laravel and PHPMailer
  • Your Gmail account, plus your email and password (Important: Your Gmail account's less secure app access must be turned on)

To turn on less secure app access of your Gmail account:

  1. Go to Gmail and sign in.
  2. Go to Manage your Google Account.Enable less secure app access in gmail - Manage your google account
  3. Go to security tab and scroll down until you see Less secure app access panel.Enable less secure app access in gmail - go to security - turn on access (not recommended)
  4. Click Turn on access (not recommended). Gmail will verify your password.
  5. Now toggle on Allow less secure apps.

Enable less secure app access in gmail

Steps to Integrate Laravel and PHPMailer

Step 1: Install Laravel Using Composer

a. Let's make sure composer works on your end. Open a command line interface. Type the command composer -v; composer version, options and available commands should be displayed.

Check if composer works correctly using composer command

Type cd command to display your current working directory. Make sure you're inside the folder where you want to install your project. If not then navigate to your preferred location using cd command, cd phpmailer.

Navigate to your preferred directory using cd command

b. Now create your Laravel project using composer create-project --prefer-dist laravel/laravel command.

The composer will download Laravel files.

Create laravel project using composer create-project --prefer-dist laravel-laravel command

It should end with the message "Application key set successfully".

Install Laravel - Application key set successfully

Step 2: Install PHPMailer Using Composer

Here we knits Laravel and PHPMailer.

a. Again, type cd command to display your current working directory. You must be inside of your project folder.

Install PHPMailer using composer require phpmailer/phpmailer command.

Install phpmailer using composer require phpmailer-phpmailer command

b. Check whether the PHPMailer exist by navigating to vendor folder. A folder named "phpmailer" must be listed together with other vendor files.

Verify if PHPMailer exist inside vendor folder

c. Start your Laravel project by executing php artisan serve command.

Start laravel project using php artisan serve command

Now open the browser of your choice and go to http://127.0.0.1:8000/. You should see Laravel's welcome page.

Laravel's welcome page

d. Run composer install command. It'll download and install all the libraries and dependencies required.

Generate optimized autoload files using composer install command

Step 3: Laravel and PHPMailer Source Code for Sending Email

a. First we have to create our controller, it'll contain our function for sending email.

Run php artisan make:Controller PhpmailerController command.

Create PHPMailer controller using php artisan make-Controller PhpmailerController

Open PhpmailerController.php located at /your-project-folder/app/Http/Controllers and paste the following code.

<?php

namespace AppHttpControllers;

use Request;

// Import PHPMailer classes into the global namespace
// These must be at the top of your script, not inside a function
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerException;

class PhpmailerController extends Controller {

	public function sendEmail (Request $request) {
  	
  	// is method a POST ?
  	if( Request::isMethod('post') ) {

			require '../vendor/autoload.php'; // load Composer's autoloader

			$mail = new PHPMailer(true); // Passing `true` enables exceptions

			try {

				// Mail server settings

				$mail->SMTPDebug = 4; // Enable verbose debug output
				$mail->isSMTP(); // Set mailer to use SMTP
				$mail->Host = 'smtp.gmail.com'; // Specify main and backup SMTP servers
				$mail->SMTPAuth = true; // Enable SMTP authentication
				$mail->Username = 'your-email@gmail.com'; // SMTP username
				$mail->Password = 'your-gmail-password'; // SMTP password
				$mail->SMTPSecure = 'tls'; // Enable TLS encryption, `ssl` also accepted
				$mail->Port = 587; // TCP port to connect to

				$mail->setFrom('your-email@gmail.com', 'Your Name');
				$mail->addAddress($_POST['email']); // Add a recipient, Name is optional
				$mail->addCC($_POST['email-cc']);
				$mail->addBCC($_POST['email-bcc']);
				$mail->addReplyTo('your-email@gmail.com', 'Your Name');
				// print_r($_FILES['file']); exit;

				for ($i=0; $i < count($_FILES['file']['tmp_name']) ; $i++) { 
					$mail->addAttachment($_FILES['file']['tmp_name'][$i], $_FILES['file']['name'][$i]); // Optional name
				}

				$mail->isHTML(true); // Set email format to HTML

				$mail->Subject = $_POST['subject'];
				$mail->Body    = $_POST['message'];
				// $mail->AltBody = plain text version of your message;

				if( !$mail->send() ) {
			    echo 'Message could not be sent.';
			    echo 'Mailer Error: ' . $mail->ErrorInfo;
				} else {
					echo 'Message has been sent';
				}

			} catch (Exception $e) {
				// return back()->with('error','Message could not be sent.');
			}
		}
  }
}

Replace the following line with your Gmail account's username and password.

$mail->Username = 'your-email@gmail.com';
$mail->Password = 'your-gmail-password';

Tips: Your PASSWORD shouldn't be hardcoded in a controller file. Maybe place those kind of data in .env or much better to store it (but hash it first) in your database.

b. We now have the logic of sending email. Now let's create our contact form.

Open /resources/views/welcome.blade.php and place the following code below.

<form role="form" method="post" action="{{ route('sendmail') }}" enctype="multipart/form-data">
	@csrf
	<div class="row">
    <div class="col-sm-9 form-group">
      <label for="email">Email to: </label>
      <input type="email" class="form-control" name="email" style="border: 1px solid black;">
    </div>
  </div>
	<div class="row">
    <div class="col-sm-9 form-group">
      <label for="email">CC: </label>
      <input type="email" class="form-control" name="email-cc" style="border: 1px solid black;">
    </div>
  </div>
	<div class="row">
    <div class="col-sm-9 form-group">
      <label for="email">BCC: </label>
      <input type="email" class="form-control" name="email-bcc" style="border: 1px solid black;">
    </div>
  </div>
  <div class="row">
    <div class="col-sm-9 form-group">
      <label for="subject">Subject: </label>
      <input type="text" class="form-control" name="subject" style="border: 1px solid black;">
    </div>
  </div>
  <div class="row">
    <div class="col-sm-9 form-group">
      <label for="name">Message: </label>
      <textarea class="form-control" type="textarea" name="message" style="border: 1px solid black;"></textarea>
    </div>
  </div>
  <div class="row">
    <div class="col-sm-9 form-group">
      <label for="name">File:</label>
      <input name="file[]" multiple="multiple" class="form-control" type="file">
    </div>
  </div>
	<div class="row">
	  <div class="col-sm-9 form-group">
			<button type="submit" name="sendmail" class="btn btn-primary">Send</button>
	  </div>
	</div>
</form>

c. Now we can setup our routing. Open /routes/web.php and paste the following code at the end.

Route::post('/sendmail',[
  'as' => 'sendmail',
  'uses' => 'AppHttpControllersPhpmailerController@sendEmail'
]);

Save and close the file.

Now go to your browser and navigate to http://127.0.0.1:8000/ and test it out. Does it work? Let me know in the comments below.

We hope this tutorial on Laravel and PHPMailer helped you add email feature to your Laravel app sitting on a localhost environment.

To improve user interface of your form and/or page, you can integrate AdminLTE in your Laravel app. Here we'll help you create a responsive web app template without starting from scratch.

11 replies
  1. Gopi chand
    Gopi chand says:

    Error when i am using your code please solve “Laravel And PHPMailer Send Email From Localhost”

    InvalidArgumentException
    Action App\Http\Controllers\PhpmailerController@sendEmail not defined. (View: C:\xampp\htdocs\milk-laravel\resources\views\contact.blade.php)

    Reply
  2. Gracielo Justine Santoso
    Gracielo Justine Santoso says:

    Symfony\Component\ErrorHandler\Error\FatalError
    App\Http\Controllers\EmailController::sendEmail(): Failed opening required ‘vendor/autoload.php’ (include_path=’C:\xampp\php\PEAR’)

    how to fix this error?

    Reply
  3. Muhiddinkhon Muhamedov
    Muhiddinkhon Muhamedov says:

    i think problem here is in namespace
    namespace AppHttpControllers; VS Code shows invalid syntax , when i try use namespace.
    Its just my mind

    Reply

Trackbacks & Pingbacks

Leave a Reply

You have any questions or suggestions? Experiencing technical issues?

Please drop a comment, we're willing to resolve any issues and improve our solutions. Let's have a personal and meaningful conversation. 😀

Leave a Reply

Your email address will not be published. Required fields are marked *

Web Developer • Technical Writer
I'm a web developer with a flair for creating elegant software solutions. I love to create and share content primarily about web development, programming, and other IT related topics.