Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

zarcoder's avatar

Laravel Contact Form

I purchased a html template from themeforest and I'm in the process of converting all the files into blade files. Bit of a mission I must say.

I now need to setup my contact form. I'm quite lost at the moment. I did read through the Laravel mail docs but I'm struggling. So the theme included the contact form (in html obviously) as well as the php 'contact-process file. Both files are shown below.

My question is, how do I convert this to laravel? I'm not sure which steps to follow. How can I make this contact form work in laravel?

The Form:

<form method="post" id="contact-form" action='contact-process.php'>
                         <label>Name</label>
                         <p><input type="text" name="name" class="reservation-fields" /></p>
                         <label>Email</label>
                         <p><input type="text" name="email" class="reservation-fields"/></p>
                         <label>Subject</label>
                         <p><input type="text" name="subject" class="reservation-fields" /></p>
                         <label>Message</label>
                         <p> <textarea name="message" id="msg-contact" class="reservation-fields" rows="7"></textarea></p>
                         <p class="antispam">Leave this empty: <input type="text" name="url" /></p>
                         <p class="contact-btn"><input type="submit" value="Send message" id="submit"/></p>
                      </form>

PHP File:

<?php

$recipient = "[email protected]";
$name = $_POST['name'];
$email = $_POST['email'];
$subject = $_POST['subject'];
$message = $_POST['message'];

if (isset($_POST['email'])) {   
    if (preg_match('(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,})', $_POST['email'])) {
        $msg = 'E-mail address is valid';
    } else {
        $msg = 'Invalid email address';
    }

  $ip = getenv('REMOTE_ADDR');
  $host = gethostbyaddr($ip);   
  $mess = "Name: ".$name."\n";
  $mess .= "Email: ".$email."\n";
  $mess .= "Subject: ".$subject."\n";
  $mess .= "Message: ".$message."\n\n";
  $mess .= "IP:".$ip." HOST: ".$host."\n";
  
  $headers = "From: <".$email.">\r\n"; 
  
   if(isset($_POST['url']) && $_POST['url'] == ''){

       $sent = mail($recipient, $subject, $mess, $headers); 
} 

  

} else {
    die('Invalid entry!');
}
0 likes
12 replies
Cronix's avatar
Cronix
Best Answer
Level 67

This doesn't seem too difficult. How familiar are you with laravel? I mean, do you know how to make forms/controllers/views/routes/validation, etc?

In short,

  1. create a post route, pointing to a controller/method
  2. In the form, change action to point to that route
  3. In form, add {{ csrf_field() }}
  4. In controller, set up validation rules for name/subject/email/message
  5. In controller, change all $_POST['var'] to $request->var
  6. In controller, use laravel Mailables to send the email
  7. In form, display validation errors. If validation fails it will send you back to the form so show the errors
1 like
zarcoder's avatar

@Cronix, I am a beginner but have done a few projects in laravel focussing on the basics. But I do know how to create, forms, controllers, views, routes and validation. I will follow your guidance and give feedback. Thanks for the reply

@newbie360 - Don't know what you're on about? I know it's front-end but has back-end functionality, hence the question.

zarcoder's avatar

@Cronin, so I got the message to work. It's being sent to mailtrap so I know it works. After the mail has been sent, I'm also being redirected to the contact page as per my redirect.

However, my success message does not display? I can't seem to get the success message right. Any thoughts?

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Session;

class PageController extends Controller
{

    public function getContact()
    {
        return view('contact');
    }

    public function postContact(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|min:2|string',
            'email' => 'required|email',
            'mobile' => 'required|digits:10',
            'message' => 'required|min:10'
        ]);

        $data = array(
          'name' => $request->name,
          'email' => $request->email,
          'mobile' => $request->mobile,
          'bodyMessage' => $request->message
        );

        Mail::send('emails.contact', $data, function($message) use ($data){
            $message->from($data['email']);
            $message->to('[email protected]');
            $message->subject($data['name']);
        });

        Session::flash('success', 'Your email has been sent');

        return redirect('contact');
    }

}
Cronix's avatar

So in the contact view, you have something like this?

@if ( session('success'))
    {{ session('success') }}
@endif 

Try

return redirect('dashboard')->with('success', 'Your email has been sent');

https://laravel.com/docs/5.6/redirects#redirecting-with-flashed-session-data

An unrelated question, is the from email address an address on your domain? If not, you will run into problems with mail delivery and possibly labeled as a spammer and have your domain put in blacklists like Spamhaus. That can take months to fix and you don't want to have to do that. You should always send from an email on your domain. You can always use the replyTo in addition and set the foreign email address there.

Mail::send('emails.contact', $data, function($message) use ($data){
    $message->from('[email protected]');
    $message->replyTo($data['email']);
    $message->to('[email protected]');
    $message->subject($data['name']);
});

Then if you hit reply in your email client, it will address it to the person who it was actually from, and ISP spam filters will be happy bc the from is your real domain.

1 like
zarcoder's avatar

Not to worry, I figured it out. Should not use

Session::flash('success', 'Your email has been sent');

Should use

$request->session()->flash('status', 'Good One');

instead

zarcoder's avatar

Sorry man, we were typing the same time it seems :). Only saw your message now

Cronix's avatar

Good deal, please see my warning about the from address.

zarcoder's avatar

please see my warning about the from address.

Thanks for the warning. So this is something new... again :). Here's my context. I'm creating a simple website for my 1st client (restaurant owner) who has a contact form on his site. He just wants to receive emails from people who want to contact him from his website.

He will then take that email and copy it into his personal email host and answer any questions.

So, as I understand it, the 'from' attribute will identify the from email address of the person enquiring. But now that I think about that, this detail is captured in one of my form fields (email).

Hhmm, ok so I should hardcode the 'from' attribute to my personal email address in order to avoid ending up in a spambox.

Isn't it better just to avoid the 'from' attribute altogether?

May be basics to you, but I'm still climbing the mountain of learning php / laravel :)

Cronix's avatar

He will then take that email and copy it into his personal email host and answer any questions.

I would just send it to his email address to begin with.

No the from field is required. When you send an email to an isp, lets say google, it checks the domain the email came from, let's say abc.com. Then it looks at the from header. If it's from anything other than abc.com, it's spam, which makes total sense.

What we do with contact forms...

  1. from is "[email protected]"
  2. to is "[email protected]"
  3. reply-to is email address person entered on form (their email, [email protected])
  4. In body of email, first thing we put is
From: [persons name] [persons email]
--------
[persons message]

So the person who receives these emails ([email protected]) can easily identify the person. If they want to reply to the email, they just hit reply like normal, but the email program will address it to the person in the "reply-to" field instead of the "from" field. This is the proper way to send email on someone elses behalf from your domain.

If the from doesn't match the domain it was actually sent from, it's spam. Some isps will bounce it, some will just discard it and you'll never know what happened to it, some will put it in the spam folder. There are millions of ISPs, and each one does things differently.

In addition, the email server needs to be set up correctly (or better yet use a service like sendgrid, etc, who know what they're doing and set it all up properly). It needs DKIM headers, RDNS set up, SPF, DMARC, and other things. The IP of the server sending the email, as well as the domain name, can't have a bad reputation or be in any blacklists. If it's a transaction email, it also needs an "opt out" link where they can remove themselves from receiving emails from your company.

Email is actually one of the more complicated things to do properly on the internet. Spam is a huge issue, and at one point (before all of these things like spf/dkim/dmarc/etc) it actually was the majority of the traffic on the internet.

Think about it. If you can just send email from a domain as another domain, that's impersonation and makes the domain that it was sent from look bad, even though they didn't actually send it.

Once you get on a blacklist (like spamhaus), it will be very difficult for other isps to receive your emails, as most of them monitor these lists in realtime and actively block emails from domains/ips that are on the lists. It will take a lot of work on your part, and several months, to get it fixed. You might end up on 10 different blacklists.

https://sendgrid.com/blog/10-tips-to-keep-email-out-of-the-spam-folder/

1 like

Please or to participate in this conversation.