Symfony4从ChoiceList改为ChoiceLoader后表单报current()参数错误
根因定位
- 警告触发位置在Symfony Form组件的
ChoiceToValueTransformer::transform()方法第32行,代码逻辑是调用current()读取choiceList->getValuesForChoices([当前Staff实体])的返回值,因传入current()的参数为null,直接触发类型不匹配警告 - 核心问题出在自定义
StaffChoiceLoader的实现:该类声明实现ChoiceLoaderInterface,但未严格遵循接口规范完成全部方法实现,两个要求返回数组的辅助方法未设置返回值,PHP隐式返回null,直接触发警告 - 附带的实现缺陷:
loadChoiceList()中使用!array_search()判断元素存在性的逻辑有bug,会将数组索引为0的合法匹配结果误判为不存在- 未对
staffService->getStaffByShop()的返回值做空值兜底,可能将null传入ChoiceList构造函数 - 自定义ChoiceLoader未明确指定实体取值回调,导致ChoiceList无法正确匹配当前表单绑定的Staff对象与可选选项集合
排查路径
- 核对
StaffChoiceLoader全量代码,确认是否补全ChoiceLoaderInterface要求的三个必须方法:loadChoiceList(callable $value = null): ChoiceListInterfaceloadChoicesForValues(array $values, callable $value = null): arrayloadValuesForChoices(array $choices, callable $value = null): array
- 检查上述两个返回数组的方法,是否存在无返回值、直接返回null的问题
- 验证
staffService->getStaffByShop()的返回值类型,确认是否为Staff实体数组,而非可空值 - 排查当前表单绑定的
Coordinate对象的wearer字段值,是否被纳入ChoiceLoader返回的可选集合范围
修复方案
- 补全
StaffChoiceLoader的接口方法实现,两个数组返回方法需严格按照规范返回匹配结果数组,通过已加载的ChoiceList完成选项与值的映射,禁止出现隐式返回null的情况 - 修复数组判断逻辑bug:将
!array_search($this->currentStaff, $staffs)替换为false === array_search($this->currentStaff, $staffs, true),避免把索引0的合法匹配误判为不存在 - 对
getStaffByShop()的返回值做空值兜底,保证传入ChoiceList构造函数的是合法数组,即使查询无结果也返回空数组 - 在
CoordinateType的wearer字段配置中,补充choice_value配置,实体关联场景下传'id'即可,保证ChoiceList可以正确完成实体对象匹配 - 调整ChoiceLoader的选项加载逻辑,确保表单当前绑定的
wearer对象会被纳入可选集合,避免出现选项不匹配的异常
内容的提问来源于stack exchange,提问作者scottie320
相关产品推荐
相关产品推荐

