gregwar/formidable

Formidable,一个务实的表单库

v2.2.1 2023-10-06 16:22 UTC

README

PHP 7 PHP 7.1 PHP 7.2 Build status paypal

Formidable 是一个用于处理表单的 PHP 库。它可以解析 HTML 表单,并允许您从 PHP 代码中操作它,然后渲染它。

它是如何工作的?

步骤 1: 下载 & 安装 Formidable

通过 composer

{
    "require": {
        "gregwar/formidable": "dev-master"
    }
}

或者克隆仓库

git clone https://github.com/Gregwar/Formidable.git

或者下载它

步骤 2: 在 HTML 中编写您的表单

首先,您必须在 HTML 中编写代码,例如

<!-- forms/example.html -->
<form method="post">
    Enter your name: 
    <input type="text" name="name" /><br />
    <input type="submit" />
</form>

步骤 3: 将其交给 Formidable

在您的 PHP 代码中,将表单交给 Formidable

<?php
session_start();
include('vendor/autoload.php');

// Formidable will parse the form and use it to check integrity
// on the server-side
$form = new Gregwar\Formidable\Form('forms/example.html');

$form->handle(function() {
    echo "Form OK!";
}, function($errors) {
    echo "Errors: <br/>";
    foreach ($errors as $error) {
        echo "$error<br />";
    }
});

echo $form;

简单,对吧?

步骤 4: 享受魔法

然后您可以使用 Formidable API 来操作您的表单

<?php

// Will set the value of the field
$form->name = "Bob";

// Will get the value of the field
$name = $form->name;

// Adds a constraint on the name
$form->addConstraint('name', function($value) {
    if (strlen($value) < 10) {
        return 'Your name should be at least 10 characters!';
    }
});

// Adds a constraint on the whole form
$form->addConstraint(function($form) {
    if ($form->getValue('pass1') != $form->getValue('pass2')) {
        return 'The passwords are different';
    }
});

您也可以直接在 HTML 代码中尝试更改表单并添加约束

<input type="text" name="name" minlength="10" />

这将强制文本在服务器端约束检查时至少为 10 个字符长。

需要 CAPTCHA 来保护您的表单吗?

<input type="captcha" name="code" />

这将生成一个图像和一个输入字段在客户端,并在服务器端使用会话来检查代码是否正确。

注意,这将使用与 Gregwar/Captcha 库的依赖关系(您将需要使用 composer 安装依赖项)。

类型

以下输入类型受支持

  • input 标签,具有类型
    • text
    • numbernumeric,查看 minmax 属性
    • intinteger,查看 minmax 属性
    • file
    • checkbox
    • radio
    • hidden
    • password
    • captcha,将自动生成一个图像
    • date,将生成三个选择框,并返回一个 DateTime 作为数据
    • multiradiomulticheckbox(请参阅源代码部分)
  • textarea
  • select

属性

请注意,某些属性不是有效的 HTML 属性,如 maxlength

<input type="text" name="name" maxlength="10" />

它不会在 HTML 表单中渲染,但将被用于检查完整性。

以下是可用属性的列表

  • minlength:值的最低长度
  • maxlength:值的最大长度
  • regex:值应遵守的正则表达式
  • min(对于数字):最小值
  • max(对于数字):最大值
  • required:告诉字段是必需的
  • readonly:字段为只读且不应修改
  • value:字段的默认值
  • min-entries:指定您应该提供多少个条目的最小数量(请参阅以下内容)
  • max-entries:指定您可以提供多少个条目的最大数量(请参阅以下内容)
  • entries:指定多个条目的最小和最大数量(请参阅以下内容)

API

您可以在您的 $form 对象上调用这些方法

  • posted():如果表单已提交则返回 true
  • check():检查表单并返回一个包含有效性错误的数组
  • handle($callback, $errorCallback):此快捷方法调用 posted 和 check(),如果表单有效则调用 $callback,否则调用 $errorCallback
  • setAttribute($field, $attr, $value):在字段上设置额外的属性
  • getAttribute($field, $attr):获取字段上的额外属性
  • source($source, $values):提供源(请参阅“源”部分)
  • setPlaceholder($name, $value):设置占位符值(见下文)
  • addConstraint($field, $callback):在字段上添加自定义约束,callback将使用字段值调用,如果没有问题应返回false,或错误字符串。如果你只传递一个闭包给它,闭包将使用表单作为参数调用,然后可以执行涉及多个字段或表单信息的测试。
  • setValue($field, $value):设置字段的值
  • getValue($field):获取字段的值
  • setValues(array $values):为一些字段设置值
  • getValues():获取所有字段的值

CSRF保护

在表单提交时,会自动插入一个额外的CSRF令牌并检查它。因此,所有表单都将得到保护。

当调用posted方法时(它在handle内部使用),使用CSRF令牌的存在性和有效性来检查表单是否已提交。

如果你在form中指定了name属性,则该特定表单的CSRF令牌将不同,这允许Formidable区分提交的是哪个表单,如果在同一页上有多个表单。

语言

可以使用setLanguage()设置错误的语言

<?php

// Will set the language to french for errors
$form->setLanguage(new Gregwar\Formidable\Language\French);

请确认你的语言在Language目录中得到支持,不要犹豫,欢迎参与其中!

源代码

您可以使用来源系统动态填充selectmultiradiomulticheckbox

<input type="multicheckbox" name="colours" source="colours" />

然后用source来填充它

<?php
$form->source('colours', array('red', 'yellow', 'blue'));

这将被一些复选框渲染

您可以使用相同的方法这样做select

<select name="colour">
    <options source="colours" />
    <option value="other">Other</option>
</select>

然后用同样的方法来来源它

从字符串创建表单

您可以从文件或从字符串创建表单,这将被自动检测

<?php

$form = new Gregwar\Formidable\Form('<form method="post">
    <select name="colour">
        <option value="blue">Blue</option>
        <option selected value="red">Red</option>
        <option value="green">Green</option>
    </select>
    </form>');

echo $form->getValue('colour') . "\n";
// red

// Sets the color to blue
$form->setValue('colour', 'blue');

echo $form;
/* Will display:
<form method="post">
    <select name="colour" >
        <option selected="selected" value="blue">Blue</option>
        <option value="red">Red</option>
        <option value="green">Green</option>
    </select>
    <input type="hidden" name="posted_token" value="d293dc38017381b6086ff1a856c1e8fe43738c60" />
</form>
*/

映射

您还可以使用mapping属性来填充表单或以数组或对象的形式检索表单数据,例如

<?php

class Person
{
    protected $name;
    public function getName() { return $this->name; }
    public function setName($name) {
        $this->name = $name;
    }
}

$person = new Person;
$person->setName('Jack');

$form = new Gregwar\Formidable\Form('<form method="post">
    <input type="text" name="name" mapping="name" />
    </form>');

$form->setData($person);

echo $form;
/*
Will output something like:

<form method="post">
    <input required="required" type="text" name="name" value="Jack" />
    <input type="hidden" name="posted_token" value="aa27f437cc6127c244db14361fd614af51c79aac" />
</form>
*/

请注意,映射使用的是Symfony PropertyAccessor,然后您可以使用类似上面的示例来填充属性。

您可以使用

  • getData($entity = array()):填充并返回填充了数据的实体
  • setData($entity):用实体属性填充表单

创建多个子表单

您可以使用<multiple>标签在页面上添加多个子表单

<form method="post">
    Film name: <input type="text" name="film_name" mapping="name" />

    <h2>Actors</h2>
    <multiple name="actors" mapping="actors">
        First name: <input name="first_name" mapping="firstName" /><br />
        Last name: <input name="last_name" mapping="lastName" /><br />
    </multiple>
    <input type="submit" />
</form>

在这种情况下,<multiple>可以像字段一样使用,但它将包含一个元素数组。

页面中将注入一些JS,允许您添加/删除一些元素。

您可以使用min-entriesmax-entries约束来设置多个的条目数量限制

如果您为min-entriesmax-entries指定相同的值,或指定一个entries的值(实际上是一个别名来做到这一点),则输入的数量将是固定的,不需要JavaScript。

向表单中添加动态数据

在某些情况下,您可能想要向表单中添加自定义数据,有两种方法可以实现。

第一种方法:使用占位符

{{ something }}语法允许您从代码中简单注入数据,例如

<?php

$form = new Gregwar\Formidable\Form('<form method="post">
    Hello {{ name }}!
    </form>');

$form->setPlaceholder('name', 'Bob');

echo $form;

在上面的示例中,{{ name }}将被渲染为Bob

请注意,除了在<form>和输入标签之外,可以始终使用占位符。

<?php

$form = new Gregwar\Formidable\Form('<form method="post">
    <span style="color:{{ color }}">Hello</span>
    </form>');

$form->setPlaceholder('color', 'red');

echo $form;

第二种方法:使用PHP表单

您也可以像模板一样编写表单,例如

<form>
    <?php echo $label; ?>: <input type="text" name="name" />
    <input type="submit" />
</form>

然后通过传递模板变量作为第二个参数来实例化表单

<?php

$form = new Gregwar\Formidable\Form('the-above-form.php', array('label' => 'Your name'));

标签 $label 将使用 PHP 进行解析。

缓存

出于性能考虑,您可能希望缓存解析后的表单。

为此,只需将 true 作为构造函数的第三个参数传递即可。

<?php

/**
 * Parsed data for the form will be serialized and stored in a cache file,
 * if you use this form often, this will offer you better performances.
 */
$form = new Gregwar\Formidable\Form('form.html', null, true);

这将使用 Gregwar/Cache 系统,您需要获取此存储库的 composer 依赖项或手动安装它。默认情况下,缓存文件将写入从运行脚本的 cache 目录。

尝试在 examples/ 目录下运行 performances.php 脚本,这将给出使用缓存的性能提升示例。

您还可以传递一个 Gregwar\Cache\Cache 实例作为第三个参数,这将允许您设置缓存目录。

许可证

Gregwar\Formidable 采用 MIT 许可证,有关更多信息,请参阅 LICENSE 文件。

历史

V2.0.0 停止支持 PHP <5.6

V2.1.0 移除对 Captcha 库的硬依赖