You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yii2单个表单更新两个数据库表数据失败的问题求助

表单数据更新失败问题排查与修复

问题概述

我创建了一个表单,尝试通过处理类和控制器实现数据更新,但提交修改后数据库中的数据并未更新,表单也仍显示原有数据。

数据库结构

person:                           Code:             Pets:
id| PersonId | name  | power      Id | PesonId      Id | Kind | PersonId | type
1 | 111      | Lufy  | Elastic    1  | 111          1  | Dog  | 190      | Dog
5 | 190      | Ace   | Fire       2  | 190          2  | Cat  | 190      | Cat

现有代码

表单模型(Form.php)

class Form extends Model
{
    /**
    * @var string
    */
    public $name;

    /**
    * @var string
    */
    public $power;

    /**
    * @var string
    */
    public $kind;
 
    public function rules()
    {
        return [['name','power','kind']];
    }

    public function attributeLabels()
    {
        return [
            'name' => 'Name',
            'power' => 'Power',
            'kind' => 'Kind' 
        ];
    }
}

视图代码

use models\Form;

/**
* @var $form Form
*/

<?php $form = ActiveForm::begin(['type' => ActiveForm::TYPE_HORIZONTAL]); ?>
<?= $form->field($form, 'name'); ?>
<?= $form->field($form, 'power'); ?>
<?= $form->field($form, 'kind'); ?>

<?= Html::sterSubmitButton('Save'); ?>

<?php
ActiveForm::end();

控制器代码(FormController.php)

class FormController extends Controller
{
    /**
     * @return string
     */
    public function actionIndex()
    {
        $form = new Form();

        if (Yii::$app->request->isPost && $form->load(Yii::$app->request->post())) {
            $formClass = new FormClass($form);
            $webshop->processForm($webshopForm);
        }

        $formClass = new FormClass($form);
        return $this->render('index', [
            'form' => $formClass->getForm(),
        ]);
    }
}

处理类代码(FormClass.php)

class ClassForm
{
    /**
    * @var Person
    */
    public $person;

    /**
    * @var Form
    */
    private $form;

    public functionn __construct(Form $form)
    {
        $this->form = $form;
        // 已登录为特定用户
        $this->person = Yii::$app->user->identity->personData;
    }

    public function getForm()
    {
        $kind = $this->person->getPetSetting(Pets::TYPE_KIND)->one();

        $this->form->name = $this->person->name;
        $this->form->power = $this->person->power;
        $this->form->name = $kind = $kind ? $kind->kind : null;

        return $this->form;
    }

    public function processForm(Form $form)
    {
        $form->save();
    }
}

关联模型代码

class Code extends ActiveRecord implements IdentityInterface
{
    public function getPersonData()
    { 
        return $this->hasOne(Person::class, ['PersonId'=>'PersonID']);
    }
}
class Person extends ActiveRecord implements IdentityInterface
{
    public function getPetSetting($type)
    { 
        return $this->hasOne(Pet::class, ['PersonId'=>'PersonID'])->andWhere(['type'=>$type]);
    }
}

问题排查与修复步骤

1. 变量名与类名错误

  • 控制器中误用未定义的$webshop和$webshopForm,应改为$formClass->processForm($form);
  • 处理类类名需与控制器实例化的FormClass一致,原类名ClassForm改为FormClass
  • 处理类构造函数拼写错误:public functionn __construct → public function __construct

2. 表单赋值错误

getForm方法中错误覆盖name字段值,应将宠物类型赋值给表单kind属性:

// 原代码
$this->form->name = $kind = $kind ? $kind->kind : null;
// 修复后
$this->form->kind = $kind ? $kind->kind : null;

3. 表单验证规则错误

Form模型的rules方法返回格式不符合Yii要求,需补充验证规则,比如必填校验:

public function rules()
{
    return [
        [['name', 'power', 'kind'], 'required'],
    ];
}

4. 提交按钮拼写错误

视图中Html::sterSubmitButton → Html::submitButton

5. 处理类未实际更新数据库

Form是普通Model,无内置save()方法,需在processForm中手动更新数据库记录:

public function processForm(Form $form)
{
    if (!$form->validate()) {
        return;
    }

    // 更新Person表
    $this->person->name = $form->name;
    $this->person->power = $form->power;
    $this->person->save(false);

    // 更新Pets表
    $pet = $this->person->getPetSetting(Pets::TYPE_KIND)->one();
    if ($pet) {
        $pet->Kind = $form->kind;
        $pet->save(false);
    } else {
        $pet = new Pets();
        $pet->PersonId = $this->person->PersonId;
        $pet->Kind = $form->kind;
        $pet->type = Pets::TYPE_KIND;
        $pet->save(false);
    }
}

6. 字段大小写一致性问题

关联模型中关联条件字段名保持统一,比如Person模型的getPetSetting方法:

return $this->hasOne(Pet::class, ['PersonId' => 'PersonId'])->andWhere(['type' => $type]);

7. 提交后刷新数据

控制器处理完提交后,重新实例化处理类以加载最新数据库数据:

if (Yii::$app->request->isPost && $form->load(Yii::$app->request->post())) {
    $formClass = new FormClass($form);
    $formClass->processForm($form);
    // 重新实例化加载最新数据
    $formClass = new FormClass($form);
}

修复后控制器代码示例

class FormController extends Controller
{
    public function actionIndex()
    {
        $form = new Form();

        if (Yii::$app->request->isPost && $form->load(Yii::$app->request->post())) {
            $formClass = new FormClass($form);
            $formClass->processForm($form);
            $formClass = new FormClass($form);
        } else {
            $formClass = new FormClass($form);
        }

        return $this->render('index', [
            'form' => $formClass->getForm(),
        ]);
    }
}

内容的提问来源于stack exchange,提问作者TLausie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 05:07:52