justcoded/form-handler

1.1 2018-07-31 12:17 UTC

This package is auto-updated.

Last update: 2024-09-21 02:47:11 UTC


README

静态表单 FormHandler 库

一个用于验证简单的 HTML 表单数据和向邮箱发送请求的小型库。此外,您可以编写自己的“处理器”来处理有效数据,例如,如果您需要通过 API 将数据保存到第三方服务(如 Mailchimp、SalesForce、CRM 系统)等。

为什么选择 FormHandler

很容易找到一些现成的解决方案来处理联系表单。通常这是一个纯 PHP 脚本,它收集数据并使用 php mail() 函数发送电子邮件。这并不坏,但您会发现这样的脚本存在许多问题

  • mail() 函数可能会在生产服务器上被阻止,因为它不安全。此外,当您使用 mail() 函数时,它通常会进入垃圾邮件文件夹。
  • 您需要验证数据是否有效。手动验证 $_POST 数组耗时且需要 PHP、RegExp 等知识。

我们决定创建一个小型库,以解决所有这些问题,因此处理表单时您需要

  • 使用简单的配置数组设置验证规则
  • 设置您的邮件设置(SMTP 设置或 Mandrill API 密钥)
  • 设置您的消息参数(发件人、收件人、主题、正文模板)

就是这样!

要求

  • PHP 7.0+
  • Composer
  • 用于发送电子邮件的工作 SMTP 服务器或配置了邮件域名的 Mandrill 账户。

用法

假设您有一个简单的 HTML 网站,其中包含一个联系表单,并希望处理它。我们有 nameemailmessage 表单字段。
我们将引导您通过创建 PHP 脚本来处理表单请求的整个过程。

1. 初始化环境

我们建议创建一个单独的文件夹来放置代码。让我们称它为 form。文件结构将如下所示

|- /form/        # folder for our code
|- contact.php   # simple HTML page with a form

/form/ 文件夹中,我们需要创建 composer.json 文件来设置我们的库要求

{
    "require": {
        "justcoded/form-handler": "*"
    }
}

现在我们需要使用 composer 下载所有必需的文件,通过运行以下 bash 命令

composer install

2. 入口文件

您必须创建一个入口文件,该文件将处理表单请求。您可以复制包文件夹中的一个示例 examples/basic.phpexamples/advanced.php

让我们将我们的文件命名为 form.php 并从头开始创建它。它应该可以从浏览器访问(例如:http://MY-DOMAIN.COM/form/form.php)。

之后,您需要包含 composer 自动加载脚本,然后设置库类使用的部分

<?php
// init autoload.
require __DIR__ . '/vendor/autoload.php';

use JustCoded\FormHandler\FormHandler;
use JustCoded\FormHandler\Handlers\MailHandler;
use JustCoded\FormHandler\DataObjects\MailMessage;
use JustCoded\FormHandler\FileManager\FileManager;

3. 表单处理

表单处理的概念非常简单。我们有一个主要的 FormHandler 对象,该对象将验证数据并运行一些处理器(目前我们只有一个处理器 - 电子邮件发送者)。作为结果,我们可以在整个过程中获取发现的错误信息。

所有这些代码都放置在 form.php 文件的末尾,如下所示

$mailer = new MailHandler($mailerConfig, new MailMessage($messageConfig));
$form = new FormHandler($validationRules, $mailer);

if ($form->validate($_POST)) {
	$form->process();
}

$result = $form->response();

// TODO: do somethign with the results. For example write to a session and redirect back.

4. 设置配置

如您所见,我们需要设置 3 个配置数组

  • $validationRules - 定义验证规则和消息
  • $mailerConfig - 定义邮件组件(PHPMailer 或 Mailchimp)及其参数
  • $messageConfig - 定义 From/To/Body 字段

4.1. 验证规则

为了验证,我们使用了流行的Valitron PHP库。我们使用mapFieldsRules()方法设置字段规则,使用labels()方法设置字段标签以正确显示错误消息。因此,您需要做的是在$validationRules数组中设置'fields''labels'键。

$validationRules = [
	'fields' => [
		'name' => ['required'],
		'email' => ['required', 'email'],
		'message' => [
			'required',
			['lengthMin', 5]
		],
	], // according to Valitron doc for mapFieldsRules().
	'labels' => [
		'name'  => 'Name',
		'email' => 'Email address',
		'message' => 'Message',
	] // according to Valitron doc for labels().
];

4.2. 邮件发送器配置

邮件发送器有两种选择:PHPMailerMandrill API的实现。

  • PHPMailer用于通过SMTP协议或PHP的mail()函数发送邮件。
  • Mandrill API用于通过Mandrill邮件服务使用其API发送邮件。

下面你可以找到这两种方法的配置数组示例

// PHPMailer config:
$mailerConfig = [
	'mailer'   => MailHandler::USE_PHPMAILER,
	'host'     => 'SMTP HOST',     // set your smtp host.
	'user'     => 'YOUR EMAIL',    // set email.
	'password' => 'YOUR PASSWORD', // set password.
	'protocol' => 'tls',           // 'tls', 'ssl' or FALSE for not secure protocol/
	'port'     => 587,             // your port.
];

// Mandrill config:
$mailerConfig = [
	'mailer'   => MailHandler::USE_MANDRILL,
	'apiKey' => 'YOUR API KEY',  // set correct API KEY.
];

4.3. 消息配置

您必须设置的最新配置是电子邮件的选项:发件人、收件人地址;主题和正文。您还可以选择设置CC和BCC头。

示例

$messageConfig = [
    'from' => ['noreply@my-domain.com' => 'My Domain Support'],
    'to' => ['admin@my-domain.com' => 'John Doe'],
    'replyTo' => ['REPLY.EMAIL@DOMAIN.COM' => 'REPLY NAME'],     // OPTIONAL
    'cc'      => ['cc-email@gmail.com', 'more-cc@gmail.com'],    // OPTIONAL
    'bcc'     => ['bcc-email@gmail.com'],                        // OPTIONAL
    'subject' => 'Contact request from {name}',
    'bodyTemplate' => __DIR__ . '/template-html.php',        // Path to HTML template
    'altBodyTemplate' => __DIR__ . '/template-plain.php',    // Path to TEXT template
];

对于每个地址字段,您都可以以这种格式设置多个电子邮件

[ email1 => name1, email2 => name2, ... ]
OR
[email1, email2, email3 ...]

bodyTemplatealtBodyTemplate是普通PHP模板文件的路径,将用于生成电子邮件消息(相应地生成HTML和纯文本版本)。

5. 整体来看

如果我们结合所有部分,我们可以得到类似这样的文件

<?php

// init autoload.
require __DIR__ . '/../vendor/autoload.php';

use JustCoded\FormHandler\FormHandler;
use JustCoded\FormHandler\Handlers\MailHandler;
use JustCoded\FormHandler\DataObjects\MailMessage;

$validationRules = [
	'fields' => [
		'name' => ['required'],
		'email' => ['required', 'email'],
		'message' => [
			'required',
			['lengthMin', 5]
		],
	], // according to Valitron doc for mapFieldsRules.
	'labels' => [
		'name'  => 'Name',
		'email' => 'Email address',
		'message' => 'Message',
	] // according to Valitron doc.
];

// SMTP config.
$mailerConfig = [
	'mailer'   => MailHandler::USE_PHPMAILER,
	'host'     => 'SMTP HOST',     // set your smtp host.
	'user'     => 'YOUR EMAIL',    // set email.
	'password' => 'YOUR PASSWORD', // set password.
	'protocol' => 'tls',           // 'tls', 'ssl' or FALSE for not secure protocol/
	'port'     => 587,             // your port.
];

// Message settings.
$messageConfig = [
	'from' => ['FROM.EMAIL@DOMAIN.COM' => 'FROM NAME'],     // set correct FROM.
	'to' => ['TO.EMAIL@DOMAIN.COM' => 'TO NAME'],           // set correct TO.
	'replyTo' => ['REPLY.EMAIL@DOMAIN.COM' => 'REPLY NAME'],// set correct REPLY.
	'subject' => 'Contact request from {name}',
	'bodyTemplate' => __DIR__ . '/template-html.php',
	'altBodyTemplate' => __DIR__ . '/template-plain.php',
];

// Run processing.
$mailer = new MailHandler($mailerConfig, new MailMessage($messageConfig));
$form   = new FormHandler($validationRules, $mailer);

if ($form->validate($_POST)) {
	$form->process();
}

// write errors and return back.
setcookie('basic_response', $form->response());
header('Location: index.php');
exit;

在这个例子中,我们写入cookie中的错误,以便能够通过JavaScript或PHP代码在HTML页面上获取它们。

6. 正文模板

模板是普通的PHP文件,可以打印您留下的任何PHP代码。然而,为了使编辑更容易,我们添加了对令牌的支持。因此,传递给FormHandler作为数据的任何键都可以用作令牌,如下所示:{key}

template-html.php 示例

<?php
/* @var array $data */
?>
<html>
<body>
<p>Hi John,</p>
<p>Someone submitted a contact form on your site with such data:</p>
<p><b>Name:</b> {name}</p>
<p><b>Email:</b> {email}</p>
<p><b>Message:</b><br>
	{message}</p>

<hr>
<p>User IP address: <?php echo @$_SERVER['REMOTE_ADDR']; ?></p>
<p>Browser: <?php echo @$_SERVER['HTTP_USER_AGENT']; ?></p>

</body>
</html>

template-plain.php 示例

<?php
/* @var array $data */
?>
Hi John,
Someone submitted a contact form on your site with such data:

Name:    {name}
Email:   {email}
Subject: {subject}
Message:

	{message}

-------

User IP address: <?php echo @$_SERVER['REMOTE_ADDR']; ?>
Browser: <?php echo @$_SERVER['HTTP_USER_AGENT']; ?>

响应格式

FormHandler可以将响应作为ARRAY或作为JSON返回。默认情况下,它返回一个JSON字符串。要更改此行为,您需要向FormHandler对象创建中添加一个额外的参数

$form   = new FormHandler($validationRules, $mailer, 'array');

一旦您收到响应,您需要将其传递到包含表单的页面以显示错误。这可以通过几种方式完成

将响应作为JSON对象传递

我们建议使用AJAX请求发送表单请求。在这种情况下,您将需要一个JSON对象作为服务器端响应

// print errors as json.
header('Content-Type: application/json; charset=utf-8');
echo $formHandler->response();
exit;

通过COOKIES传递响应

如果您使用cookie,则可以使用JavaScript在网站上显示错误,在这种情况下不需要PHP知识。

// set cookie with form status/errors and redirect back
setcookie('form_status', $form->response());
header('Location: index.php');
exit;

通过SESSION传递响应

如果您想用PHP代码处理错误,那么使用会话传递错误是更好的选择

// start session if not started:
session_start();
// set sesson with form status/errors and redirect back
$_SESSION['form_status'] = $form->response();
header('Location: index.php');
exit;

响应数组

在成功的情况下

{"status":true,"errors":[]}

在发生错误的情况下

{"status":false,"errors":{"field1": ["Error1", "Error2"], "field2": ["Error3", "Error4"]}}

文件上传和邮件附件

表单处理程序还支持文件上传并将它们作为电子邮件附件发送。

要添加此功能,您还需要一个名为FileManager的类

// Configure the location of attachments directory 
// it should be writable and accessible from browser
$fileManager = new FileManager([
    'uploadPath' => __DIR__ . '/attachments',           // folder path to save files to 
    'uploadUrl' => 'http://MY-DOMAIN.COM/attachments',  // site URL to this folder
]);

之后,您需要指定哪些文件应该上传到$messageConfig

$messageConfig = [
	'from' => ['FROM.EMAIL@DOMAIN.COM' => 'FROM NAME'],     // set correct FROM.
	'to' => ['TO.EMAIL@DOMAIN.COM' => 'TO NAME'],           // set correct TO.
	'replyTo' => ['REPLY.EMAIL@DOMAIN.COM' => 'REPLY NAME'],// set correct REPLY.
	'subject' => 'Contact request from {name}',
	'bodyTemplate' => __DIR__ . '/template-html.php',
	'altBodyTemplate' => __DIR__ . '/template-plain.php',
	
    'attachments' => $fileManager->upload([
        'input_file_name1', 'input_file_name2', // ...
    ])
];

input_file_name1input_file_name2是文件输入的名称属性

<input type="file" name="input_file_name1">
<input type="file" name="input_file_name2">
...

当然,每个邮件服务器都有最大附件大小的限制。通常不超过10MB。要正确设置此限制,您需要使用附加选项更新$mailerConfig

$mailerConfig = [
	'mailer'   => MailHandler::USE_PHPMAILER, // or USE_MANDRILL
	...

	'attachmentsSizeLimit' => 8388608, // 8MB in Bytes.
];

所有附件都上传到指定的目录,我们建议在正文/替代正文模板中添加附件链接。要打印文件链接,您需要编写一个具有输入文件名的令牌。如下所示

...
<p>Attachments: {input_file_name1}, {input_file_name2}</p>
...

如果您需要验证文件具有特定的类型或大小,您可以使用我们定制的"file"验证器

$validationRules = [
	'fields' => [
		// ...
		'input_file_name1' => [  // this is file field.
			[
				'file',
				['jpeg', 'jpg', 'png', 'pdf'], // types.
				2000000,                       // size limit around 2 MB.
				'message' => '{field} should be up to 2MB and allows only file types jpeg, png.',
			],
		],
		...
];

多字段

一些表单可能有多个字段,如复选框、多选框或动态创建的输入。

示例

<!-- multiple select -->
<select name="choice" multiple>
	<option value="1">1</option>
	<option value="2">2</option>
	<option value="3">3</option>
</select>

<!-- text inputs -->
<input type="text" name="links[]">
<input type="text" name="links[]">
<input type="text" name="links[]">

您可以使用通配符字段名在*验证规则内验证每个输入。

$validationRules = [
	'fields' => [
		// ...
		'choice.*' => ['int'],
		'links.*'  => ['url'],
		...
];

与文件附件类似,您可以使用令牌一次性打印所有值。它们将以逗号分隔。

模板使用

...
<p>Choice: {choice}</p>
<p>Links: {links}</p>

示例

您可以在包的examples文件夹中查看工作示例,从index.php文件(包含表单HTML)开始您的调查。在那里,您可以找到提交表单时加载的下一个文件。