问题描述
CakePHP以某种方式保存了两次相同的数据。由于某种原因,我想实现此add方法,以便当有人直接进入domain.com/recordings/add
看起来很简单,我一直在挠头。我检查了验证错误;我尝试过禁用验证;我尝试改用patchEntity()
。
但是,有一件奇怪的事,如果您通过点击domain.com/recordings/add
中的add recording
按钮进入domain.com/recordings/index
(而不是在浏览器中输入网址),保存一次。
控制器:
public function add()
{
$dummy = [
"user_id" => 1,"title" => "tgfbthgdthb","body" => "rgcvfghfhdxcgb","published" => 0,];
$recording = $this->Recordings->newEntity($dummy);
$this->Recordings->save($recording);
}
模型/表格:
public function initialize(array $config): void
{
parent::initialize($config);
$this->setTable('recordings');
$this->setdisplayField('title');
$this->setPrimaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Users',[
'foreignKey' => 'user_id','joinType' => 'INNER',]);
$this->hasMany('Words',[
'foreignKey' => 'recording_id',]);
}
模型/实体:
protected $_accessible = [
'user_id' => true,'title' => true,// 'slug' => true,'body' => true,'published' => true,'created' => true,'modified' => true,'user' => true,'words' => true,];
视图:
<?PHP
/**
* @var \App\View\AppView $this
* @var \App\Model\Entity\Recording $recording
*/
?>
<div class="row">
<aside class="column">
<div class="side-nav">
<h4 class="heading"><?= __('Actions') ?></h4>
<?= $this->Html->link(__('List Recordings'),['action' => 'index'],['class' => 'side-nav-item']) ?>
</div>
</aside>
<div class="column-responsive column-80">
<div class="recordings form content">
<?= $this->Form->create($recording) ?>
<fieldset>
<legend><?= __('Add Recording') ?></legend>
<?PHP
echo $this->Form->control('user_id',['options' => $users]);
echo $this->Form->control('title');
echo $this->Form->control('body');
echo $this->Form->control('published');
?>
</fieldset>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</div>
</div>
</div>
解决方法
不要试图适应人们的懒惰,不要让他们仅通过访问URL(即通过GET
请求)来保存数据,这只会造成麻烦,最重要的是它是不好的应用程序设计。
至少应采取适当的保护措施,仅为POST
个请求保存数据。
浏览器可能会在各种情况下发出多个请求,从预检OPTIONS
请求到奇怪的怪癖,例如,如果在响应数据的前x个字节中找不到任何编码信息,Firefox将中止该请求,然后发出一个新请求,该请求采用针对响应的特定编码。
public function add()
{
if ($this->request->is('post')) {
// save data here
}
}