[TOC]
# 表单
`Phalcon\Forms\Form` 是一个有助于在Web应用程序中创建和维护表单的组件。
以下示例显示了其基本用法:
```php
<?php
use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Select;
$form = new Form();
$form->add(
new Text(
'name'
)
);
$form->add(
new Text(
'telephone'
)
);
$form->add(
new Select(
'telephoneType',
[
'H' => 'Home',
'C' => 'Cell',
]
)
);
```
可以根据表单定义呈现表单:
```php
<h1>
Contacts
</h1>
<form method='post'>
<p>
<label>
Name
</label>
<?php echo $form->render('name'); ?>
</p>
<p>
<label>
Telephone
</label>
<?php echo $form->render('telephone'); ?>
</p>
<p>
<label>
Type
</label>
<?php echo $form->render('telephoneType'); ?>
</p>
<p>
<input type='submit' value='Save' />
</p>
</form>
```
表单中的每个元素都可以根据开发人员的要求进行渲染。在内部,`Phalcon\Tag` 用于为每个元素生成正确的HTML,您可以将其他HTML属性作为`render()`的第二个参数传递:
```php
<p>
<label>
Name
</label>
<?php echo $form->render('name', ['maxlength' => 30, 'placeholder' => 'Type your name']); ?>
</p>
```
HTML属性也可以在元素的定义中设置:
```php
<?php
$form->add(
new Text(
'name',
[
'maxlength' => 30,
'placeholder' => 'Type your name',
]
)
);
```
## 初始化表单
如前所述,可以通过向表单类添加元素来在表单类之外初始化表单。您可以在单独的文件中重用代码或组织实现表单的表单类:
```php
<?php
use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Select;
class ContactForm extends Form
{
public function initialize()
{
$this->add(
new Text(
'name'
)
);
$this->add(
new Text(
'telephone'
)
);
$this->add(
new Select(
'telephoneType',
TelephoneTypes::find(),
[
'using' => [
'id',
'name',
],
'useEmpty' => true,
'emptyText' => 'Select one...',
'emptyValue' => '',
]
)
);
}
}
```
此外,Select元素支持 `useEmpty` 选项,以便在可用选项列表中使用空白元素。选项`emptyText ` 和 `emptyValue`是可选的,它允许您分别自定义文本和空元素的值
`Phalcon\Forms\Form` 继承了 `Phalcon\Di\Injectable` 因此您可以根据需要访问应用程序服务:
```php
<?php
use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Hidden;
class ContactForm extends Form
{
/**
* This method returns the default value for field 'csrf'
*/
public function getCsrf()
{
return $this->security->getToken();
}
public function initialize()
{
// Set the same form as entity
$this->setEntity($this);
// Add a text element to capture the 'email'
$this->add(
new Text(
'email'
)
);
// Add a text element to put a hidden CSRF
$this->add(
new Hidden(
'csrf'
)
);
}
}
```
在初始化和自定义用户选项中添加到表单的关联实体将传递给表单构造函数:
```php
<?php
use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\Hidden;
class UsersForm extends Form
{
/**
* Forms initializer
*
* @param Users $user
* @param array $options
*/
public function initialize(Users $user, array $options)
{
if ($options['edit']) {
$this->add(
new Hidden(
'id'
)
);
} else {
$this->add(
new Text(
'id'
)
);
}
$this->add(
new Text(
'name'
)
);
}
}
```
在表单的实例化中,您必须使用:
```php
<?php
$form = new UsersForm(
new Users(),
[
'edit' => true,
]
);
```
## 验证
Phalcon表单与`validation`组件集成,以提供即时验证。可以为每个元素设置内置或自定义验证器:
```php
<?php
use Phalcon\Forms\Element\Text;
use Phalcon\Validation\Validator\PresenceOf;
use Phalcon\Validation\Validator\StringLength;
$name = new Text(
'name'
);
$name->addValidator(
new PresenceOf(
[
'message' => 'The name is required',
]
)
);
$name->addValidator(
new StringLength(
[
'min' => 10,
'messageMinimum' => 'The name is too short',
]
)
);
$form->add($name);
```
然后,您可以根据用户输入的输入验证表单:
```php
<?php
if (!$form->isValid($_POST)) {
$messages = $form->getMessages();
foreach ($messages as $message) {
echo $message, '<br>';
}
}
```
验证器的执行顺序与注册顺序相同。
默认情况下,表单中所有元素生成的消息都已连接,因此可以使用单个foreach遍历它们,您可以更改此行为以获取由字段分隔的消息:
```php
<?php
foreach ($form->getMessages(false) as $attribute => $messages) {
echo 'Messages generated by ', $attribute, ':', "\n";
foreach ($messages as $message) {
echo $message, '<br>';
}
}
```
或获取元素的特定消息:
```php
<?php
$messages = $form->getMessagesFor('name');
foreach ($messages as $message) {
echo $message, '<br>';
}
```
## 过滤
表单还可以在验证之前过滤数据。您可以在每个元素中设置过滤器:
```php
<?php
use Phalcon\Forms\Element\Text;
$name = new Text(
'name'
);
// Set multiple filters
$name->setFilters(
[
'string',
'trim',
]
);
$form->add($name);
$email = new Text(
'email'
);
// Set one filter
$email->setFilters(
'email'
);
$form->add($email);
```
>[info] 阅读过滤相关章节,了解有关在Phalcon中过滤的更多信息。
## Forms + Entities
可以将模型/集合/普通实例或纯PHP类等实体链接到表单,以便在表单元素中设置默认值,或者轻松地将表单中的值分配给实体:
```php
<?php
$robot = Robots::findFirst();
$form = new Form($robot);
$form->add(
new Text(
'name'
)
);
$form->add(
new Text(
'year'
)
);
```
一旦表单被渲染,如果没有为元素分配默认值,它将使用实体提供的值:
```php
<?php echo $form->render('name'); ?>
```
您可以通过以下方式验证表单并从用户输入中分配值:
```php
<?php
$form->bind($_POST, $robot);
// Check if the form is valid
if ($form->isValid()) {
// Save the entity
$robot->save();
}
```
也可以将普通类设置为实体:
```php
<?php
class Preferences
{
public $timezone = 'Europe/Amsterdam';
public $receiveEmails = 'No';
}
```
将此类用作实体,允许表单从中获取默认值:
```php
<?php
$form = new Form(
new Preferences()
);
$form->add(
new Select(
'timezone',
[
'America/New_York' => 'New York',
'Europe/Amsterdam' => 'Amsterdam',
'America/Sao_Paulo' => 'Sao Paulo',
'Asia/Tokyo' => 'Tokyo',
]
)
);
$form->add(
new Select(
'receiveEmails',
[
'Yes' => 'Yes, please!',
'No' => 'No, thanks',
]
)
);
```
实体可以实现具有比公共属性更高优先级的getter。这些方法使您可以更自由地生成值:
```php
<?php
class Preferences
{
public $timezone;
public $receiveEmails;
public function getTimezone()
{
return 'Europe/Amsterdam';
}
public function getReceiveEmails()
{
return 'No';
}
}
```
## 表单元素
Phalcon提供了一组在表单中使用的内置元素,所有这些元素都位于`Phalcon\Forms\Element`命名空间中:
| 名称 | 描述 |
|----------------------------------|---------------------------------------------------------------|
| `Phalcon\Forms\Element\Check` | 生成 `INPUT[type=check]` 元素 |
| `Phalcon\Forms\Element\Date` | 生成 `INPUT[type=date]` 元素 |
| `Phalcon\Forms\Element\Email` | 生成 `INPUT[type=email]` 元素 |
| `Phalcon\Forms\Element\File` | 生成 `INPUT[type=file]` 元素 |
| `Phalcon\Forms\Element\Hidden` | 生成 `INPUT[type=hidden]` 元素 |
| `Phalcon\Forms\Element\Numeric` | 生成 `INPUT[type=number]` 元素 |
| `Phalcon\Forms\Element\Password` | 生成 `INPUT[type=password]` 元素 |
| `Phalcon\Forms\Element\Radio` | 生成 `IMPUT[type=radio]` 元素 |
| `Phalcon\Forms\Element\Select` | 根据选择生成 `SELECT` 标记 (组合列表)元素 |
| `Phalcon\Forms\Element\Submit` | 生成 `INPUT[type=submit]` 元素 |
| `Phalcon\Forms\Element\Text` | 生成 `INPUT[type=text]` 元素 |
| `Phalcon\Forms\Element\TextArea` | 生成 `TEXTAREA` 元素 |
## 事件回调
每当表单作为类实现时,回调:`beforeValidation()`和`afterValidation()`可以在表单的类中实现,以执行预验证和后验证:
```php
<?php
use Phalcon\Forms\Form;
class ContactForm extends Form
{
public function beforeValidation()
{
}
}
```
## 渲染表单
您可以完全灵活地渲染表单,以下示例显示如何使用标准过程渲染每个元素:
```php
<br /><form method='post'>
<?php
// Traverse the form
foreach ($form as $element) {
// Get any generated messages for the current element
$messages = $form->getMessagesFor(
$element->getName()
);
if (count($messages)) {
// Print each element
echo '<div class='messages'>';
foreach ($messages as $message) {
echo $message;
}
echo '</div>';
}
echo '<p>';
echo '<label for='', $element->getName(), ''>', $element->getLabel(), '</label>';
echo $element;
echo '</p>';
}
?>
<input type='submit' value='Send' />
</form>
```
或者重用表单类中的逻辑:
```php
<?php
use Phalcon\Forms\Form;
class ContactForm extends Form
{
public function initialize()
{
// ...
}
public function renderDecorated($name)
{
$element = $this->get($name);
// Get any generated messages for the current element
$messages = $this->getMessagesFor(
$element->getName()
);
if (count($messages)) {
// Print each element
echo "<div class='messages'>";
foreach ($messages as $message) {
echo $this->flash->error($message);
}
echo '</div>';
}
echo '<p>';
echo '<label for="', $element->getName(), '">', $element->getLabel(), '</label>';
echo $element;
echo '</p>';
}
}
```
在视图中:
```php
<?php
echo $element->renderDecorated('name');
echo $element->renderDecorated('telephone');
```
## 创建表单元素
除了Phalcon提供的表单元素,您还可以创建自己的自定义元素:
```php
<?php
use Phalcon\Forms\Element;
class MyElement extends Element
{
public function render($attributes = null)
{
$html = // ... Produce some HTML
return $html;
}
}
```
## 表单管理器
该组件提供了一个表单管理器,开发人员可以使用它来注册表单并通过服务定位器访问它们:
```php
<?php
use Phalcon\Forms\Manager as FormsManager;
$di['forms'] = function () {
return new FormsManager();
};
```
表单将添加到表单管理器并由唯一名称引用:
```php
<?php
$this->forms->set(
'login',
new LoginForm()
);
```
使用唯一名称,可以在应用程序的任何部分访问表单:
```php
<?php
$loginForm = $this->forms->get('login');
echo $loginForm->render();
```
## 外部资源
* [Vökuró](http://vokuro.phalconphp.com)是一个示例应用程序,它使用表单构建器来创建和管理表单, [[Github](https://github.com/phalcon/vokuro)]
- 常规
- Welcome
- 贡献
- 生成回溯
- 测试重现
- 单元测试
- 入门
- 安装
- Web服务器设置
- WAMP
- XAMPP
- 教程
- 基础教程
- 教程:创建一个简单的REST API
- 教程:Vökuró
- 提升性能
- 教程:INVO
- 开发环境
- Phalcon Compose (Docker)
- Nanobox
- Phalcon Box (Vagrant)
- 开发工具
- Phalcon开发者工具的安装
- Phalcon开发者工具的使用
- 调试应用程序
- 核心
- MVC应用
- 微应用
- 创建命令行(CLI)应用程序
- 依赖注入与服务定位
- MVC架构
- 服务
- 使用缓存提高性能
- 读取配置
- 上下文转义
- 类加载器
- 使用命名空间
- 日志
- 队列
- 数据库
- 数据库抽象层
- Phalcon查询语言(PHQL)
- ODM(对象文档映射器)
- 使用模型
- 模型行为
- ORM缓存
- 模型事件
- 模型元数据
- 模型关系
- 模型事务
- 验证模型
- 数据库迁移
- 分页
- 前端
- Assets管理
- 闪存消息
- 表单
- 图像
- 视图助手(标签)
- 使用视图
- Volt:模板引擎
- 业务逻辑
- 访问控制列表(ACL)
- 注解解析器
- 控制器
- 调度控制器
- 事件管理器
- 过滤与清理
- 路由
- 在session中存储数据
- 生成URL和路径
- 验证
- HTTP
- Cookies管理
- 请求环境
- 返回响应
- 安全
- 加密/解密
- 安全
- 国际化
- 国际化
- 多语言支持