以 Task 實體為例:
// src/Acme/TaskBundle/Entity/Task.php
namespace Acme\TaskBundle\Entity;
class Task {
protected $task;
protected $dueDate;
public function getTask() { return $this->task; }
public function setTask($task) { $this->task = $task; }
public function getDueDate() { return $this->dueDate; }
public function setDueDate(\DateTime $dueDate = null) { $this->dueDate = $dueDate; }
}
控制器中使用 FormBuilder:
$task = new Task();
$task->setTask('Write a blog post');
$task->setDueDate(new \DateTime('tomorrow'));
$form = $this->createFormBuilder($task)
->add('task', 'text')
->add('dueDate', 'date')
->getForm();
return $this->render('AcmeTaskBundle:Default:new.html.twig', ['form' => $form->createView()]);
Twig 完整渲染:
<form action="{{ path('task_new') }}" method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<input type="submit" />
</form>
單獨渲染欄位(彈性排版):
{{ form_errors(form) }}
{{ form_row(form.task) }}
{{ form_row(form.dueDate) }}
{{ form_rest(form) }}
手動渲染每個元素:
{{ form_label(form.task) }}
{{ form_errors(form.task) }}
{{ form_widget(form.task, {'attr': {'class': 'task_field'}}) }}
public function newAction(Request $request) {
$task = new Task();
$form = $this->createFormBuilder($task)
->add('task', 'text')
->add('dueDate', 'date')
->getForm();
if ($request->isMethod('POST')) {
$form->handleRequest($request); // Symfony 2.3+ 建議用 handleRequest
if ($form->isValid()) {
// 儲存至資料庫
$em = $this->getDoctrine()->getManager();
$em->persist($task);
$em->flush();
return $this->redirect($this->generateUrl('task_success'));
}
}
return $this->render(...);
}
支援 YAML、Annotations、XML、PHP 四種格式。以 Annotations 為例:
use Symfony\Component\Validator\Constraints as Assert;
class Task {
/** @Assert\NotBlank() */ public $task;
/** @Assert\NotBlank() @Assert\Type("\DateTime") */ protected $dueDate;
}
required:預設 true,控制 HTML5 必填屬性(仍需伺服端驗證)。label:自訂標籤文字。widget:如 date 類型可設 single_text 渲染單一輸入框。// src/Acme/TaskBundle/Form/Type/TaskType.php
namespace Acme\TaskBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class TaskType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder->add('task');
$builder->add('dueDate', null, ['widget' => 'single_text']);
}
public function getName() { return 'task'; }
public function getDefaultOptions(array $options) {
return ['data_class' => 'Acme\TaskBundle\Entity\Task'];
}
}
控制器使用:$form = $this->createForm(new TaskType(), $task);
將 CategoryType 嵌入 TaskType:
$builder->add('category', new CategoryType());
模板渲染:{{ form_row(form.category.name) }}
自訂 field_row 區塊:
{# src/Acme/TaskBundle/Resources/views/Form/fields.html.twig #}
{% block field_row %}
{% spaceless %}
<div class="form_row">
{{ form_label(form) }}
{{ form_errors(form) }}
{{ form_widget(form) }}
</div>
{% endspaceless %}
{% endblock %}
於模板引入:{% form_theme form 'AcmeTaskBundle:Form:fields.html.twig' %}
預設啟用,隱藏欄位 _token。可於表單類別自訂:
public function getDefaultOptions(array $options) {
return [
'csrf_protection' => true,
'csrf_field_name' => '_token',
'intention' => 'task_item',
];
}
直接回傳陣列資料:
$form = $this->createFormBuilder(['message' => 'Type your message'])
->add('name', 'text')
->add('email', 'email')
->add('message', 'textarea')
->getForm();
// 提交後 $form->getData() 回傳陣列
驗證規則可傳入 validation_constraint 選項。