【问题标题】:CakePHP 4 FormProtector instance has not been created errorCakePHP 4 FormProtector 实例尚未创建错误
【发布时间】: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');

?>

AppControllerinitialize 函数中我有这个:

$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-&gt;unlockField() 函数。 我显然在我的代码中调用了Form-&gt;create(),这是因为我包含了一个元素来向“主”模板中定义的表单添加字段吗?还是有其他解释?

我已经尝试添加

$this->loadComponent('FormProtection');

致我的AppController,但这会在应用程序的许多其他地方引起更多问题,并且无论如何都不能解决问题(页面呈现,但在提交要保存的表单时出现错误数据)。

【问题讨论】:

  • 是否是因为它在一个元素中,您可以通过将代码直接放在模板中而不是使用元素来轻松检查,或者只是删除它(这不太可能,因为它们共享相同查看实例)。您还应该检查异常的堆栈跟踪以确定 unlockField() 调用错误的确切来源,以确保它不是来自您没想到的地方。
  • @ndm 错误确实来自unlockField 元素中的第一个unlockField 调用。我还尝试在主模板中复制粘贴代码而不是使用元素,我得到了同样的错误。
  • 通常安全组件应该可以正常工作,虽然它已被弃用,但它的表单保护功能仍然完好无损。错误消息鼓励升级,但这在技术上不是必需的。我建议您在控制器操作和模板中调试请求,以确定安全组件是否正确设置了所需的 formTokenData 属性,并且它不会在途中丢失: debug($this-&gt;request-&gt;getAttribute('formTokenData'));
  • @ndm 我确实在 CakePHP 的 FormHelper 中调试了请求,发现当它被另一个随机表单调用时,formTokenData 属性存在,而在导致错误的特定表单中它不存在.但我不明白为什么,因为我在两个模板中都调用了“Form->create()”。我什至在 FormHelper 中打印了堆栈跟踪,它完全一样(当然减去不同的模板),所以这两个调用中似乎没有任何额外或缺失的方法。
  • 按照建议,也可以在您的控制器操作中进行调试,以确定该属性是否可能在某个时候丢失,或者从一开始就不会出现。要获得更准确的结果,请在安全组件内部进行调试,可能一开始就没有设置。

标签: php cakephp cakephp-4.x


【解决方案1】:

是否有可能在元素DataLayers/layer-tableactions/add 中发生了一些意想不到的事情?

如果Form-&gt;end() 在这些元素之一中过早运行,可能会导致您看到的问题。

我在使用View Blocks 时遇到过类似的表单问题。但我没有看到证据表明这对你来说是个问题。

表单内的视图块似乎发生的情况是,模板(或元素)已呈现,并且在处理视图块之前关闭了表单。

Form helper 看起来就像一个一次性对象,它的方法必须按顺序调用; create()几乎所有其他方法end()。一旦end() 被调用,Helper 对象基本上就死了,直到再次调用create()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-29
    • 1970-01-01
    • 1970-01-01
    • 2018-11-27
    • 2021-08-28
    • 1970-01-01
    相关资源
    最近更新 更多