PHP项目Symfony form与单选按钮

wen PHP项目 1

本文目录导读:

PHP项目Symfony form与单选按钮

  1. 基本单选按钮(ChoiceType)
  2. 使用RadioType
  3. 实体关联的单选按钮
  4. 自定义选项属性
  5. 在Twig模板中的渲染
  6. 完整示例:用户注册表单
  7. 使用Bootstrap 5样式
  8. 验证规则
  9. 注意事项

在Symfony中处理表单的单选按钮(radio button)有以下几种方式,我为你详细介绍:

基本单选按钮(ChoiceType)

// src/Form/UserFormType.php
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
class UserFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('gender', ChoiceType::class, [
                'choices' => [
                    '男' => 'male',
                    '女' => 'female',
                    '其他' => 'other',
                ],
                'expanded' => true,  // 设置为true显示为单选按钮
                'multiple' => false, // 单选
                'label' => '性别',
            ]);
    }
}

使用RadioType

use Symfony\Component\Form\Extension\Core\Type\RadioType;
$builder
    ->add('agree', RadioType::class, [
        'label' => '我同意条款',
        'value' => 'yes',
        'required' => true,
    ]);

实体关联的单选按钮

// 假设有Category实体
$builder
    ->add('category', EntityType::class, [
        'class' => Category::class,
        'choice_label' => 'name',
        'expanded' => true,  // 显示为单选按钮
        'multiple' => false,
        'label' => '选择分类',
    ]);

自定义选项属性

$builder
    ->add('payment', ChoiceType::class, [
        'choices' => [
            '微信支付' => 'wechat',
            '支付宝' => 'alipay',
            '银行卡' => 'bank',
        ],
        'expanded' => true,
        'multiple' => false,
        'choice_attr' => function($choice, $key, $value) {
            return ['data-type' => $value];
        },
        'label_attr' => [
            'class' => 'radio-inline'
        ],
    ]);

在Twig模板中的渲染

{# 使用form_row #}
{{ form_row(form.gender) }}
{# 手动渲染 #}
{% for child in form.gender %}
    <div class="radio">
        <label>
            {{ form_widget(child) }}
            {{ form_label(child) }}
        </label>
    </div>
{% endfor %}
{# 带Bootstrap样式 #}
<div class="form-group">
    <label class="control-label">{{ form_label(form.gender) }}</label>
    <div class="radio-group">
        {% for child in form.gender %}
            <label class="radio-inline">
                {{ form_widget(child) }}
                {{ form_label(child) }}
            </label>
        {% endfor %}
    </div>
</div>

完整示例:用户注册表单

// src/Form/RegistrationFormType.php
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\FormBuilderInterface;
class RegistrationFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email', EmailType::class)
            ->add('password', PasswordType::class)
            ->add('gender', ChoiceType::class, [
                'choices' => [
                    '男' => 'male',
                    '女' => 'female',
                    '其他' => 'other',
                ],
                'expanded' => true,
                'multiple' => false,
                'label' => '性别',
                'placeholder' => false, // 不显示空选项
                'data' => 'male', // 默认值
            ])
            ->add('subscribe', ChoiceType::class, [
                'choices' => [
                    '是' => true,
                    '否' => false,
                ],
                'expanded' => true,
                'multiple' => false,
                'label' => '订阅通知',
                'data' => true,
            ]);
    }
}

使用Bootstrap 5样式

{# templates/registration/register.html.twig #}
{% form_theme form 'bootstrap_5_layout.html.twig' %}
{# 自定义渲染 #}
{% block _user_form_gender_row %}
    <div class="mb-3">
        <label class="form-label">{{ form_label(form) }}</label>
        <div class="btn-group" role="group">
            {% for child in form %}
                <input type="radio" 
                       class="btn-check" 
                       name="{{ child.vars.full_name }}" 
                       id="{{ child.vars.id }}" 
                       value="{{ child.vars.value }}"
                       {{ child.vars.checked ? 'checked' : '' }}>
                <label class="btn btn-outline-primary" for="{{ child.vars.id }}">
                    {{ child.vars.label }}
                </label>
            {% endfor %}
        </div>
    </div>
{% endblock %}

验证规则

// src/Entity/User.php
use Symfony\Component\Validator\Constraints as Assert;
class User
{
    /**
     * @Assert\NotBlank(message="请选择性别")
     * @Assert\Choice(choices={"male", "female", "other"}, message="无效的性别选项")
     */
    private $gender;
    // getters/setters
}

注意事项

  1. expanded属性:设置为true显示为单选按钮
  2. multiple属性:设置为false表示单选
  3. 数据绑定:单选按钮的值会绑定到实体的对应属性
  4. 默认值:通过data选项设置默认选中项
  5. 模板渲染:可以使用原生Twig或Bootstrap表单主题

选择哪种方式取决于你的具体需求:

  • 简单选项用ChoiceType
  • 需要数据库关联用EntityType
  • 特殊样式需求用自定义模板

需要我详细介绍某个具体场景的实现吗?

抱歉,评论功能暂时关闭!