【发布时间】:2022-07-12 11:03:37
【问题描述】:
我目前正在将一个(相当大的)应用程序从 CakePHP 3 更新到 4。
我有这个模板:
<?= $this->Form->create(
$dmpLayer,
[
'url' => [
'controller' => 'DmpLayers',
'action' => 'edit',
],
]
); ?>
<div class="row">
<div class="col-4">
<?= $this->element('DataLayers/layer-table'); ?>
</div>
<div id="form-div" class="col-6">
<div class="layer-form">
<?= $this->element('DataLayers/form') ?>
</div>
</div>
<div class="col-2">
<div class="layer-form">
<h2>Form Actions</h2>
<?= $this->Form->submit('Create/Update Layer', ['class' => 'btn btn-success']); ?>
</div>
</div>
</div>
<?= $this->Form->end(); ?>
<?= $this->Html->script('data-layers'); ?>
其中包括DataLayers/form 元素:
<div class="row">
<div class="col-12">
<h4>Artist Layer</h4>
<?php
echo $this->Html->tag('fieldset', $this->element(
'actions/add',
[
'url' => [
'prefix' => 'Admin',
'plugin' => false,
'controller' => 'SegmentCores',
'action' => 'add',
],
]
)
. $this->Form->control('artist_layer.segment_cores[]', [
'multiple',
'options' => $segmentCores,
'label' => 'Segment Core',
'value' => $selectedValues['segment_cores'],
])
. $this->Form->control('artist_layer.segment_potentials[]', [
'multiple',
'options' => $segmentPotentials,
'label' => 'Segment Potential',
'value' => $selectedValues['segment_potentials'],
])
. $this->Form->control('artist_layer.layer_tags[]', [
'multiple',
'options' => $layerTags,
'label' => 'Artist Tag',
'value' => $selectedValues['artist_tags'],
])
. $this->Form->control('artist_layer.genres[]', [
'empty' => 'No genre set',
'options' => $genres,
'label' => 'Genre',
'value' => $selectedValues['genres'],
]);
?>
</div>
</div>
<?php
$this->Form->unlockField('artist_layer.genres');
$this->Form->unlockField('artist_layer.segment_cores');
$this->Form->unlockField('artist_layer.segment_potentials');
$this->Form->unlockField('artist_layer.layer_tags');
?>
在AppController 的initialize 函数中我有这个:
$this->loadComponent('Security');
当我访问该页面时,它没有呈现,我立即收到此错误:
FormProtector instance has not been created. Ensure you have loaded the FormProtectionComponent in your controller and called FormHelper::create() before calling FormHelper::unlockField()
这是我的应用程序中发生此错误的唯一表单。其他所有表单都运行良好,我在其中许多表单中都调用了Form->unlockField() 函数。
我显然在我的代码中调用了Form->create(),这是因为我包含了一个元素来向“主”模板中定义的表单添加字段吗?还是有其他解释?
我已经尝试添加
$this->loadComponent('FormProtection');
致我的AppController,但这会在应用程序的许多其他地方引起更多问题,并且无论如何都不能解决问题(页面呈现,但在提交要保存的表单时出现错误数据)。
【问题讨论】:
-
是否是因为它在一个元素中,您可以通过将代码直接放在模板中而不是使用元素来轻松检查,或者只是删除它(这不太可能,因为它们共享相同查看实例)。您还应该检查异常的堆栈跟踪以确定
unlockField()调用错误的确切来源,以确保它不是来自您没想到的地方。 -
@ndm 错误确实来自
unlockField元素中的第一个unlockField调用。我还尝试在主模板中复制粘贴代码而不是使用元素,我得到了同样的错误。 -
通常安全组件应该可以正常工作,虽然它已被弃用,但它的表单保护功能仍然完好无损。错误消息鼓励升级,但这在技术上不是必需的。我建议您在控制器操作和模板中调试请求,以确定安全组件是否正确设置了所需的
formTokenData属性,并且它不会在途中丢失:debug($this->request->getAttribute('formTokenData')); -
@ndm 我确实在 CakePHP 的 FormHelper 中调试了请求,发现当它被另一个随机表单调用时,
formTokenData属性存在,而在导致错误的特定表单中它不存在.但我不明白为什么,因为我在两个模板中都调用了“Form->create()”。我什至在 FormHelper 中打印了堆栈跟踪,它完全一样(当然减去不同的模板),所以这两个调用中似乎没有任何额外或缺失的方法。 -
按照建议,也可以在您的控制器操作中进行调试,以确定该属性是否可能在某个时候丢失,或者从一开始就不会出现。要获得更准确的结果,请在安全组件内部进行调试,可能一开始就没有设置。
标签: php cakephp cakephp-4.x