[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管理
- 請求環境
- 返回響應
- 安全
- 加密/解密
- 安全
- 國際化
- 國際化
- 多語言支持