如何创建Laravel联系表单并使用SendGrid发送电子邮件

来自菜鸟教程
跳转至:导航、​搜索

作为 Write for DOnations 计划的一部分,作者选择了 Open Source Initiative 来接受捐赠。

介绍

Laravel 是一个免费的开源 PHP 框架,基于 Symfony,用于创建 Web 应用程序。 SendGrid 是一个基于云的 SMTP 提供程序,允许您发送电子邮件而无需维护电子邮件服务器。

在您的网站上有一个联系表可以让您的访问者更容易直接与您联系。 为了使您的联系表正常工作并发送电子邮件,您需要一个 SMTP 服务器。 本教程将使用 SendGrid 和他们的免费 SMTP 服务将从网站联系表发送的电子邮件发送到电子邮件收件箱。

在本教程中,您将向现有的 Laravel 应用程序添加一个联系表单,并将其配置为使用 SendGrid 通过 SMTP 发送电子邮件。

先决条件

如果您还没有设置 Laravel 应用程序,您将需要以下内容:

  • 以具有 sudo 权限的非 root 用户身份访问 Ubuntu 20.04 服务器,并在您的服务器上安装活动防火墙。 要设置这些,请参阅我们的 Ubuntu 20.04 初始服务器设置指南。
  • 按照 如何在 Ubuntu 20.04 上安装 Nginx、MySQL 和 PHP,在您的服务器上安装 LEMP 堆栈。
  • Composer 安装 Laravel 及其依赖项。 您可以按照我们关于 如何在 Ubuntu 20.04 上安装 Composer 的指南安装 Composer。
  • 在您的服务器上安装和配置 Laravel。 如果您还没有安装 Laravel,您可以按照我们的 如何在 Ubuntu 20.04 上使用 Nginx 安装和配置 Laravel 教程。

设置好 Laravel 应用程序后,您还需要以下内容:

  • 一个 SendGrid 帐户。 您可以访问SendGrid注册页面注册一个免费的SendGrid账号。
  • 完全注册的域名指向您的服务器。 本教程将自始至终使用 your_domain。 您可以在 Namecheap 上购买一个域名,在 Freenom 上免费获得一个域名,或者使用您选择的域名注册商。 对于 DigitalOcean,您可以按照此 DigitalOcean DNS 介绍了解如何添加它们的详细信息。

第 1 步 - 创建发件人身份

SendGrid 要求您在允许您开始发送电子邮件之前验证您的域名的所有权。 为了验证您的域名,请转到您的 SendGrid 帐户,然后转到 Dashboard 并单击 Authenticate your Domain

这将带您到一个页面,您需要在该页面中指定您的 DNS 主机并选择是否要为您的域的链接添加品牌。 电子邮件链接品牌化允许您将电子邮件中用于点击跟踪的所有链接设置到您的域,而不是来自 sendgrid.net

然后单击 Next 并在下一页上指定您的域名。

最后,您需要添加 SendGrid 提供的 DNS 记录以完成其验证过程。 有关如何管理 DNS 记录的更多信息,您可以阅读本教程 如何创建、编辑和删除 DNS 记录

将 DNS 记录添加到 DNS 区域后,返回 SendGrid 并点击 Verify 按钮。

验证您的 SendGrid 身份后,您需要生成一个 API 密钥,您将在 Laravel .env 文件中使用它。

在左侧菜单中,单击 API Keys,然后单击 Create API Key 按钮。 为了安全起见,将 API Key Permissions 设置为 Restricted Access

之后,向下滚动并添加 Mail Send 权限。

最后,点击创建和查看按钮以获取您的 API 密钥。 API 密钥只能显示一次,因此请务必在安全的地方记下它。

现在您已经使用 SendGrid 配置了您的域并生成了您的 API 密钥,您将为您的 Laravel 应用程序配置 SMTP 详细信息。

第 2 步 — 配置 SMTP 详细信息

Laravel 中的 .env 文件用于存储应用程序环境的各种配置选项。 由于 .env 文件中通常包含一些敏感信息,例如您的数据库连接详细信息,因此您不应将 .env 文件提交到源代码管理。

如果您完成了先决条件教程,则需要在 /var/www/travellist 目录中访问您的 .env 文件:

cd /var/www/travellist

之后,使用您喜欢的文本编辑器打开 .env 文件:

nano .env

.env 文件中有许多配置变量——在本教程中,您将只更改 MAIL 变量。

为此,请找到 MAIL_ 设置并按以下方式配置变量,将复制的 API 密钥添加到 sendgrid_api_key 并根据需要更新其他突出显示的字段:

.env

. . .
MAIL_MAILER=smtp
MAIL_HOST=smtp.sendgrid.net
MAIL_PORT=587
MAIL_USERNAME=apikey
MAIL_PASSWORD=sendgrid_api_key
MAIL_ENCRYPTION=tls
. . .

以下列表包含了为了让 Laravel 应用程序开始使用 SendGrid SMTP 服务器而必须更新的变量的概述:

  • MAIL_HOST:SendGrid SMTP 主机名,将用于发送电子邮件。
  • MAIL_PORT:SendGrid 安全 TLS SMTP 端口。
  • MAIL_USERNAME:您的 SendGrid 用户名。 默认情况下,所有帐户为 apikey
  • MAIL_PASSWORD:您的 SendGrid API 密钥。
  • MAIL_ENCRYPTION:邮件加密协议。 在这种情况下,您将使用 TLS,因为它在服务器之间传输期间保护电子邮件内容。

保存并退出文件。

设置好 SMTP 后,您就可以继续并配置您的联系人控制器了。

第三步——创建控制器

接下来,您将创建一个控制器来处理您对联系表单页面的 POSTGET 请求。

您将使用 GET 路由返回包含您的联系表单的 HTML 页面,并且 POST 路由将处理联系表单提交。

为了在 Laravel 中创建一个名为 ContactController 的控制器,请使用以下 artisan 命令:

php artisan make:controller ContactController

运行命令后,您将获得以下输出:

OutputController created successfully.

此命令将在 app/Http/Controllers/ContactController.php 处创建一个新控制器。

运行以下命令来编辑 ContactController.php 文件:

nano app/Http/Controllers/ContactController.php

首先,您将包含 Laravel Mail 外观,以便您可以在新控制器中使用邮件功能。 Laravel 中的 facade 是一个提供对不同 Laravel 功能的访问的类。 有关 Laravel Facades 的更多信息,请查看 官方 Laravel Facades 文档

要包含 Laravel Mail 外观,请添加以下内容:

应用程序/Http/Controllers/ContactController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Mail;
. . .

然后添加将处理您的 GET 请求并返回联系人页面视图的方法:

应用程序/Http/Controllers/ContactController.php

. . .
class ContactController extends Controller
{
        public function contact(){
                return view('contact');
        }
}

最后,让我们添加一个方法来处理 POST 请求并发送电子邮件:

应用程序/Http/Controllers/ContactController.php

...
class ContactController extends Controller
{
        public function contact(){
                return view('contact');
        }

    public function contactPost(Request $request){
        $this->validate($request, [
                        'name' => 'required',
                        'email' => 'required|email',
                        'comment' => 'required'
                ]);

        Mail::send('email', [
                'name' => $request->get('name'),
                'email' => $request->get('email'),
                'comment' => $request->get('comment') ],
                function ($message) {
                        $message->from('youremail@your_domain');
                        $message->to('youremail@your_domain', 'Your Name')
                        ->subject('Your Website Contact Form');
        });

        return back()->with('success', 'Thanks for contacting me, I will get back to you soon!');

    }
}

在突出显示的行中,您需要更改一些变量,如下所示:

  • $message->from('youremail@your_domain');:将 youremail@your_domain 更改为您的实际电子邮件地址。
  • $message->to('youremail@your_domain', 'Your Name')$message->to$message->from不一定要匹配。 您还可以将 $message->to 值更改为您希望接收所有联系表查询的另一个电子邮件地址。
  • subject('Your Website Contact Form');:您也可以通过编辑subject方法内的消息来更改电子邮件主题。

注意$message->from('youremail@your_domain');地址需要与您在SendGrid中使用的域名相匹配。


完成这些编辑后,以下将是您的完整 ContactController.php 文件:

应用程序/Http/Controllers/ContactController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Mail;

class ContactController extends Controller
{
    public function contact(){
        return view('contact');
    }

    public function contactPost(Request $request){
        $this->validate($request, [
                        'name' => 'required',
                        'email' => 'required|email',
                        'comment' => 'required'
                ]);

        Mail::send('email', [
                'name' => $request->get('name'),
                'email' => $request->get('email'),
                'comment' => $request->get('comment') ],
                function ($message) {
                        $message->from('youremail@your_domain');
                        $message->to('youremail@your_domain', 'Your Name')
                                ->subject('Your Website Contact Form');
        });

        return back()->with('success', 'Thanks for contacting me, I will get back to you soon!');

    }
}

完成编辑后保存并退出文件。

您的联系人控制器有两种方法:

  • contact():此方法返回您的联系人 Blade 视图模板,该模板将保存您的 HTML 页面,该页面具有您的联系表单的 HTML 布局。 Blade 是 Laravel 自带的模板引擎。 在您的 Blade 模板视图中,您可以添加 HTML 结构以及 PHP 代码和 Blade 语法。
  • contactPost():此方法处理所有联系表单提交——您在其中处理输入验证并发送电子邮件。

您使用 $this->validate() 方法处理 contactPost() 方法内部的验证。 在验证方法中,您指定 nameemailcomment 是必需的。 这样,您的用户将无法提交空的或不完整的联系表单查询。 有关 Laravel 验证如何工作的更多信息,请查看 官方 Laravel 验证文档

验证成功后,Mail::send() 方法会构造您的电子邮件正文和主题,然后发送电子邮件。

最后,如果电子邮件发送成功,您会返回一条成功消息,该消息会显示给您的用户。

您已经设置了您的联系人控制器,现在可以继续使用 GETPOST 路由。

第 4 步 - 创建路由

Laravel 路由允许你为你的应用程序创建对 SEO 友好的 URL。 通过使用 Laravel 路由,您可以将您的应用程序请求路由到特定的控制器,您可以在其中处理您的应用程序逻辑。

您将在 routes/web.php 文件中创建两条路线,以使用您在上一步中设置的方法。

您将首先创建一个 GET 路由,该路由映射到 ContactController 中的 contact 方法。 此方法仅返回您的 contact 刀片视图。 使用以下命令打开 routes/web.php

nano routes/web.php

在文件底部添加 GET 路由:

注意:如果你遵循了先决条件,你的routes/web.php文件中会有不同的内容。 您可以按照本教程中的说明将您的路线添加到此文件的末尾。


路线/web.php

<?php
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/contact', 'ContactController@contact')->name('contact');

您现在将添加一个 POST 路由并将其映射到您的 contactPost 方法,该方法将处理您的用户联系表单提交:

路线/web.php

<?php
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/contact', 'ContactController@contact')->name('contact');
Route::post('/contact', 'ContactController@contactPost')->name('contactPost');

准备好 Controller 和 Route 后,您可以保存并退出文件,然后继续下一步,准备 Blade 视图。

第 5 步 - 创建刀片视图

在这一步中,您将首先在应用程序中创建一个视图,该视图将保存您的 HTML 联系表单。 它将具有三个输入字段:

  • 带有用户电子邮件地址类型文本的输入字段
  • 用户名的输入字段,类型为文本
  • 评论的文本区域

创建一个名为 resources/views/contact.blade.php 的文件:

nano resources/views/contact.blade.php

然后添加以下内容:

资源/视图/contact.blade.php

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Contact Form with Laravel and SendGrid</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
        integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">
</head>

<body>

    <div class="container">
        @if(session('success'))
        <div class="alert alert-success">
          {{ session('success') }}
        </div>
        @endif

        <form method="POST" action="/contact">
            @csrf
            <div class="form-group {{ $errors->has('name') ? 'has-error' : '' }}">
                <label for="email">Email address</label>
                <input name="email" type="email" class="form-control" id="email" aria-describedby="emailHelp"
                    placeholder="Enter your email">
                <span class="text-danger">{{ $errors->first('email') }}</span>
            </div>
            <div class="form-group {{ $errors->has('name') ? 'has-error' : '' }}">
                <label for="name">Name</label>
                <input name="name" type="text" class="form-control" id="name" aria-describedby="name" placeholder="Your name">
                <span class="text-danger">{{ $errors->first('name') }}</span>

            </div>
            <div class="form-group {{ $errors->has('name') ? 'has-error' : '' }}">
                <label for="exampleInputPassword1">Comment</label>
                <textarea name="comment" class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
                <span class="text-danger">{{ $errors->first('comment') }}</span>
            </div>
            <button type="submit" class="btn btn-primary">Submit</button>
        </form>
    </div>

</body>

</html>

这是一个 HTML 表单,带有 POST 方法到 /contact 路由。 当有人填写联系表时,将由您的 contactPost 方法处理。

<head> 标签内的 <link> 标签用于包含 Bootstrap。 您正在为 HTML 表单使用一些样式。 您可以更改表单的样式,使其与您网站的设计相匹配。 有关如何设置网站样式的更多信息,您可以查看我们的 CSS 资源页面

表单包含在不同的 <div> 标签中,带有来自 Bootstrap 的类。 您正在使用 <div> 标签来创建联系表单的结构。 有关如何<div>标签有效,请查看如何使用

, HTML 内容划分元素教程。 保存并退出此文件。

您将创建的下一个视图是您的电子邮件视图。

打开resources/views/email.blade.php文件:

nano resources/views/email.blade.php

然后添加以下内容:

资源/视图/email.blade.php

Inquiry from: {{ $name }}
<p> Email: {{ $email }} </p>
<p> Message: {{ $comment }} </p>

这包含将发送给完成您的联系表的用户的电子邮件内容。 保存并退出文件。

样式和视图完成后,您就可以继续测试联系表单了。

第 6 步 - 测试联系表

要测试联系表,请通过浏览器访问 http://your_domain/contact

您将看到在上一步中创建的 Bootstrap HTML 表单。

填写所有必填字段并点击 提交 按钮。 您将收到一条消息已成功发送的绿色通知。

您可以通过提交表单来测试表单,而无需填写任何字段。 您在控制器中添加的验证会捕捉到这一点,它会通知您字段不能为空。

最后,您可以检查您的电子邮件帐户并确保您已收到测试电子邮件,并且您可以在收件箱中看到它。

结论

您现在已经成功地将联系表添加到您现有的 Laravel 网站。

您还可以在 官方 Laravel 文档 中找到更多信息。

为确保您的联系表是安全的,您可以按照我们关于 How To Secure Nginx with Let's Encrypt 的指南为您的网站安装 SSL 证书。

要了解有关 Laravel 的更多信息,请查看我们的 Laravel 资源集合