justcoded / form-handler
Requires
- mandrill/mandrill: 1.0.*
- phpmailer/phpmailer: ^6.0
- vlucas/valitron: ^1.4
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 网站,其中包含一个联系表单,并希望处理它。我们有 name
、email
和 message
表单字段。
我们将引导您通过创建 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.php
或 examples/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. 邮件发送器配置
邮件发送器有两种选择:PHPMailer和Mandrill 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 ...]
bodyTemplate
和altBodyTemplate
是普通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_name1
和input_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)开始您的调查。在那里,您可以找到提交表单时加载的下一个文件。